2016-02-28 9 views
0

Я пытаюсь создать самозаверяющий сертификат. Я хочу сделать это, чтобы сохранить ключ Spongey Castle Keypair в «AndroidKeyStore». Подпись должна быть ECDSA для P-256 с дайджестом SHA-256.Самостоятельный сертификат 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

ok. в нижней строке я пытаюсь смешать поставщиков криптографии (губчатый против 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