如何找到 Android 和 iOS 的可信证书?
How to find trusted certificate for both Android and iOS?
免责声明是自问自答
我有好几次遇到这样的情况,即我们的客户在 iOS 购买了被视为 "trusted" 的证书,但不幸的是,在 Android 上它不起作用。
是什么原因造成的,如何解决?
简短的回答是购买普通的可信证书。
原因是 Android 设备上的信任库包含不同的可信证书集 -- IOS 和 Android 可信证书不同。
可以用集合来描述:
A -- android 可信证书
我 -- iOS 可信证书
AI -- 可信证书的交集
因此,我们需要这两个平台的交集。
但是,这个问题变得更加复杂,因为 Android 和 iOS 的受信任证书集因 OS 版本而异。这意味着我们将需要查看所有受支持的平台及其所有受支持的版本,以找到一组通用的受支持证书。
iOS 的受信任证书列表可在其官方网站上找到 list of supported iOS certificates
对于 Android 我没有找到相同的列表,但可以通过下面的代码从运行时获取它。
public List<CertificateDto> getCertificates() {
List<CertificateDto> result = new ArrayList<>();
try {
String algorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(algorithm);
trustManagerFactory.init((KeyStore) null);
X509TrustManager xtm = (X509TrustManager) trustManagerFactory.getTrustManagers()[0];
for (X509Certificate cert : xtm.getAcceptedIssuers()) {
PublicKey publicKey = cert.getPublicKey();
int leyLength = 0;
if (publicKey instanceof RSAPublicKey) {
leyLength = ((RSAPublicKey) publicKey).getModulus().bitLength();
} else if (publicKey instanceof DSAPublicKey) {
leyLength = ((DSAPublicKey) publicKey).getY().bitLength();
}
CertNameToValidNameConverter validNameConverter = new CertNameToValidNameConverter();
CertificateDto certificate = new CertificateDto();
certificate.setSubjectName(validNameConverter.convert(cert.getSubjectDN().getName()));
certificate.setIssuerName(validNameConverter.convert(cert.getIssuerDN().getName()));
certificate.setKeyLength(leyLength);
certificate.setTypeAlg(cert.getSigAlgName());
certificate.setExpirationDate(cert.getNotAfter().getTime());
result.add(certificate);
}
} catch (NoSuchAlgorithmException e) {
Log.e(App.TAG, "Failed obtain list of certificates", e);
} catch (KeyStoreException e) {
Log.e(App.TAG, "Failed obtain list of certificates", e);
}
return result;
}
当您从受支持的 Android OS 中获取证书列表时,您将需要编写脚本来查看所有证书并将其与来自不同受支持 [=42= 的另一个列表进行比较] 版本,之后还有 iOS 版本。您将需要比较证书名称、颁发者名称、算法类型、签名算法和密钥长度。过期日期也用于验证,但您可以省略它。
我通过从 excel 解析 IOS 8,9 和 Android 6.0 的证书来实现此脚本, 4.4 和 4.1.
您可以在下面找到最终的证书列表。从 ~220 IOS 个证书和 ~150 个证书中,您只能为两个平台使用 ~65 个证书
list of supported certificates for both Android and iOS (google drive link)
免责声明是自问自答
我有好几次遇到这样的情况,即我们的客户在 iOS 购买了被视为 "trusted" 的证书,但不幸的是,在 Android 上它不起作用。
是什么原因造成的,如何解决?
简短的回答是购买普通的可信证书。
原因是 Android 设备上的信任库包含不同的可信证书集 -- IOS 和 Android 可信证书不同。
可以用集合来描述:
A -- android 可信证书
我 -- iOS 可信证书
AI -- 可信证书的交集
因此,我们需要这两个平台的交集。
但是,这个问题变得更加复杂,因为 Android 和 iOS 的受信任证书集因 OS 版本而异。这意味着我们将需要查看所有受支持的平台及其所有受支持的版本,以找到一组通用的受支持证书。
iOS 的受信任证书列表可在其官方网站上找到 list of supported iOS certificates
对于 Android 我没有找到相同的列表,但可以通过下面的代码从运行时获取它。
public List<CertificateDto> getCertificates() {
List<CertificateDto> result = new ArrayList<>();
try {
String algorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(algorithm);
trustManagerFactory.init((KeyStore) null);
X509TrustManager xtm = (X509TrustManager) trustManagerFactory.getTrustManagers()[0];
for (X509Certificate cert : xtm.getAcceptedIssuers()) {
PublicKey publicKey = cert.getPublicKey();
int leyLength = 0;
if (publicKey instanceof RSAPublicKey) {
leyLength = ((RSAPublicKey) publicKey).getModulus().bitLength();
} else if (publicKey instanceof DSAPublicKey) {
leyLength = ((DSAPublicKey) publicKey).getY().bitLength();
}
CertNameToValidNameConverter validNameConverter = new CertNameToValidNameConverter();
CertificateDto certificate = new CertificateDto();
certificate.setSubjectName(validNameConverter.convert(cert.getSubjectDN().getName()));
certificate.setIssuerName(validNameConverter.convert(cert.getIssuerDN().getName()));
certificate.setKeyLength(leyLength);
certificate.setTypeAlg(cert.getSigAlgName());
certificate.setExpirationDate(cert.getNotAfter().getTime());
result.add(certificate);
}
} catch (NoSuchAlgorithmException e) {
Log.e(App.TAG, "Failed obtain list of certificates", e);
} catch (KeyStoreException e) {
Log.e(App.TAG, "Failed obtain list of certificates", e);
}
return result;
}
当您从受支持的 Android OS 中获取证书列表时,您将需要编写脚本来查看所有证书并将其与来自不同受支持 [=42= 的另一个列表进行比较] 版本,之后还有 iOS 版本。您将需要比较证书名称、颁发者名称、算法类型、签名算法和密钥长度。过期日期也用于验证,但您可以省略它。
我通过从 excel 解析 IOS 8,9 和 Android 6.0 的证书来实现此脚本, 4.4 和 4.1.
您可以在下面找到最终的证书列表。从 ~220 IOS 个证书和 ~150 个证书中,您只能为两个平台使用 ~65 个证书
list of supported certificates for both Android and iOS (google drive link)