2016-02-28 78 views
0

我正嘗試創建一個自簽名證書。 我想這樣做是爲了將海綿城堡KeyPair存儲到「AndroidKeyStore」中。 簽名需要是帶有SHA-256摘要的P-256的ECDSA。Spongey Castle自簽證書與Android KeyStore?

// see http://www.programcreek.com/java-api-examples/index.php?class=org.spongycastle.cert.X509v3CertificateBuilder&method=addExtension 
X509Certificate genSelfSignedCert(KeyPair kp, String CN){ 
    X509Certificate certificate; 

    try{ 
     X500Name x500Name = new X500NameBuilder(BCStyle.INSTANCE) 
          .addRDN(BCStyle.CN, CN) 
          .build(); 

     SecureRandom rand = new SecureRandom(); 
     PrivateKey privKey = kp.getPrivate(); 
     PublicKey pubKey = kp.getPublic(); 

     SubjectPublicKeyInfo subPubKeyInfo = SubjectPublicKeyInfo.getInstance(ASN1Sequence.getInstance(pubKey.getEncoded())); 

     Date startDate = new Date(); // now 

     Calendar c = Calendar.getInstance(); 
     c.setTime(startDate); 
     c.add(Calendar.YEAR, 1); 
     Date endDate = c.getTime(); 

     X509v3CertificateBuilder v3CertGen = new X509v3CertificateBuilder(
         x500Name, 
         BigInteger.valueOf(rand.nextLong()), 
         startDate, endDate, 
         x500Name, 
         subPubKeyInfo); 


     ContentSigner sigGen = new JcaContentSignerBuilder("SHA256withECDSA").build(privKey); 
     X509CertificateHolder certHolder = v3CertGen.build(sigGen); 
     certificate = new JcaX509CertificateConverter().getCertificate(certHolder); 
    }//try 
    catch(OperatorCreationException| CertificateException X) {;} 

    mLog.debug("kp.getPublic().getAlgorithm(): \t" + kp.getPublic().getAlgorithm()); 
    mLog.debug("certificate.getPublicKey().getAlgorithm():\t" + certificate.getPublicKey().getAlgorithm()); 

    return certificate; 
}//genSelfSignedCert() 

當我用上面的方法genSelfSignedCert()(從ProgramCreek.com拍攝)

X509Certificate[] selfSignedCert = new X509Certificate[1]; 
selfSignedCert[0] = genSelfSignedCert(keyPair, "MyAwesomeAlias"); 
KeyStore.Entry privateKey = new PrivateKeyEntry(keyPair.getPrivate(), selfSignedCert); 

我得到:

kp.getPrivate().getAlgorithm(): ECDSA 
kp.getPublic().getAlgorithm(): ECDSA 
certificate.getPublicKey().getAlgorithm(): EC <--MISMATCH!? Why not ECDSA? 

IllegalArgumentException: 
Algorithm of private key does not match algorithm of public key in end certificate of entry (with index number: 0) 

爲什麼這個方法創建一個證書,其算法不匹配它的密鑰對?

回答

0

好的。底線是我想混合加密提供者(海綿與AndroidKeyStore)。

我決定不這樣做,但如果你想混加密提供商必須切換相應的,像這樣:

//Moves provider to first place 
static void initSecurity(java.security.Provider provider){ 
    listProviders(); 
    java.security.Security.removeProvider(provider.getName()); 

    int insertProviderAt = java.security.Security.insertProviderAt(provider, 1); 
    mLog.debug("insertProviderAt:\t" + Integer.toString(insertProviderAt)) ; 
    listProviders(); 
}//initSecurity 



static public void listProviders(){ 
    java.security.Provider[] providers = java.security.Security.getProviders(); 
    StringBuilder list = new StringBuilder().append("Num providers: " + providers.length); 
    int i = 0; 
    for (java.security.Provider p : providers){ 
     list.append("\n\tProvider " + ++i + ": " + p.getName() + "\t info: " + p.getInfo()); 
     java.util.Set<java.security.Provider.Service> services = p.getServices(); 
     list.append("\tNum services: " + services.size()); 
     for (java.security.Provider.Service s : services){ 
      //list.append("\n\t\tService: " + s.toString() + "\ttype: " + s.getType() + "\talgo: " + s.getAlgorithm()); 
     } 
    } 

    mLog.debug(list.toString()); 
}//listProviders