Я посмотрел ответ от «emmby» (ответил 16 июня '11 в 21:29), пункт № 4: «Создайте собственный SSLSocketFactory, который использует встроенный сертификат KeyStore, но использует альтернативный KeyStore для все, что не удается проверить по умолчанию. "
Это упрощенная реализация. Загрузите системное хранилище ключей & amp; объединить с хранилищем ключей приложения.
public HttpClient getNewHttpClient() {
try {
InputStream in = null;
// Load default system keystore
KeyStore trusted = KeyStore.getInstance(KeyStore.getDefaultType());
try {
in = new BufferedInputStream(new FileInputStream(System.getProperty("javax.net.ssl.trustStore"))); // Normally: "/system/etc/security/cacerts.bks"
trusted.load(in, null); // no password is "changeit"
} finally {
if (in != null) {
in.close();
in = null;
}
}
// Load application keystore & merge with system
try {
KeyStore appTrusted = KeyStore.getInstance("BKS");
in = context.getResources().openRawResource(R.raw.mykeystore);
appTrusted.load(in, null); // no password is "changeit"
for (Enumeration e = appTrusted.aliases(); e.hasMoreElements();) {
final String alias = e.nextElement();
final KeyStore.Entry entry = appTrusted.getEntry(alias, null);
trusted.setEntry(System.currentTimeMillis() + ":" + alias, entry, null);
}
} finally {
if (in != null) {
in.close();
in = null;
}
}
HttpParams params = new BasicHttpParams();
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);
SSLSocketFactory sf = new SSLSocketFactory(trusted);
sf.setHostnameVerifier(SSLSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
registry.register(new Scheme("https", sf, 443));
ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);
return new DefaultHttpClient(ccm, params);
} catch (Exception e) {
return new DefaultHttpClient();
}
}
Простой режим для преобразования из JKS в BKS:
keytool -importkeystore -destkeystore cacerts.bks -deststoretype BKS -providerclass org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath bcprov-jdk16-141.jar -deststorepass changeit -srcstorepass changeit -srckeystore $JAVA_HOME/jre/lib/security/cacerts -srcstoretype JKS -noprompt
* Примечание. В Android 4.0 (ICS) изменилось хранилище доверия, дополнительная информация: http: // nelenkov.blogspot.com.es/2011/12/ics-trust-store-implementation.html
Версия typedef - это частный случай
typedef foo bar;
, который определяет новый «тип» bar как псевдоним для foo. В вашем случае foo оказывается структурой. В C это был единственный способ ввести новые «типы» (в кавычках, потому что они на самом деле не эквивалентны int, float и co). В C ++ это не так полезно, потому что C ++ был разработан, чтобы сделать определение новых типов более простым и полным, чем C (по крайней мере, в начале C ++), а typedef даже не требуется для ссылки на ранее объявленную структуру ( или класс).
Вот различия между двумя объявлениями / определениями:
1) Вы не можете использовать имя typedef для идентификации конструктора или деструктора
struct MyStruct { MyStruct(); ~MyStruct(); }; // ok
typedef struct { MyStructTD(); ~MyStructTD(); } MyStructTD; // not ok
// now consider
typedef struct MyStruct2 { MyStruct2(); } MyStructTD2; // ok
MyStructTD2::MyStruct2() { } // ok
MyStructTD2::MyStructTD2() { } // not ok
2) Вы не можете скрыть имя typedef например, вы можете ввести имя через заголовок класса - или, наоборот, если у вас уже есть функция или объект с определенным именем, вы все равно можете объявить класс с этим именем, используя заголовок класса, но не через подход typedef.
struct MyStruct { }; // ok
typedef struct { } MyStructTD; // ok
void MyStruct() { } // (1) - ok Hides struct MyStruct
void MyStructTD() { } // (2) - not-ok - ill-formed
//> Or if you flip it around, consider in a new translation unit:
void MyStruct() { } // ok
void MyStructTD() { } // ok
struct MyStruct { }; // ok
typedef struct { } MyStructTD; // Not ok
3) Вы не можете использовать имя typedef в подробном описателе типа
struct MyStruct { }; // ok
typedef struct { } MyStructTD; // ok
int main()
{
void MyStruct();
void MyStructTD(); // ok - new declarative region
struct MyStruct ms; // ok - names the type
struct MyStructTD ms2; // not ok - cannot use typedef-name here
}
struct AnotherStruct
{
friend struct MyStruct; // ok
friend struct MyStructTD; // not ok
};
4) Вы не можете использовать его для определения вложенных структур
struct S { struct M; };
typedef struct { } S::M; // not ok
struct S::M { }; // ok
Как видите, между ними есть заметная разница. Некоторые причуды typedefs являются результатом совместимости с C (именно поэтому, я считаю, существуют оба способа) - и в большинстве случаев объявление имени в заголовке класса более естественно для C ++ - оно имеет свои преимущества (особенно когда вам нужно определить конструкторы и деструкторы) и поэтому предпочтительнее. Если вы пишете код, который должен быть совместим с C и C ++, то есть преимущества от использования обоих подходов. Но если вы пишете чистый C ++, я считаю, что указание имени класса в заголовке класса более читабельно.
Последний предназначен для совместимости с C - используйте первый в новом коде C ++.
Вы должны использовать typedef, поэтому вам не нужно указывать ключевое слово struct при объявлении переменных этой структуры.
Без typedef:
struct MyStruct foo;
С typedef:
MyStruct foo;
В основном вы создание MyStruct как нового типа, поэтому он также реализует некоторый уровень абстракции типов, поскольку программистам не нужно явно знать, какой это тип. Вы можете передать MyStruct в функцию, управлять данными в ней и возвращать их, и программисту не нужно беспокоиться о том, что на самом деле происходит.
Большая часть стандартной библиотеки C использует typedef по этой причине.
"struct MyStruct {};" construct неявно определяет эквивалентный typedef, поэтому обычно это предпочтительное современное использование. Есть еще несколько применений typedef, в основном с указателями на структуры. Например,
typedef struct MyStruct* MyStructPtr;
Есть много ответов, в которых оба подхода рассматриваются как эквивалентные, но это не так.
Ключевое слово typedef
используется для создания псевдонима типа, то есть обеспечивает новый способ ссылки на другой тип. Когда вы используете typedef struct {} XXX;
, вы фактически создаете безымянный тип, а затем создаете псевдоним XXX для этого безымянного типа. С другой стороны, когда вы набираете struct XXX {}
.
Пожалуйста, прочтите ответ Майкла Берра здесь (это лучший ответ, чем тот, который был принят на этот вопрос .