2016-04-27 111 views
0

我在做RSA加密和解密在我的应用程序中。我有两个文件放置在assets文件夹中,public_key.cer用于加密,private_key.cer用于解密.Getting我从下面的文件中获取公钥。获取异常,同时试图从证书中获取私钥

CertificateFactory certFactory = CertificateFactory.getInstance(X.509, BC); 
InputStream is = context.getAssets().open("public_Key.cer"); 
X509Certificate cert = (X509Certificate) certFactory.generateCertificate(is); 
publicKey = cert.getPublicKey(); 

RSA加密做工精细,而我面临的问题,而试图从certificate.Below获得privae关键是使用获得的私钥

InputStream is = context.getAssets().open("private_key.cer"); 
PKCS8EncodedKeySpec privSpec = new PKCS8EncodedKeySpec(new BASE64Decoder().decodeBuffer(is)); 
KeyFactory keyFactory = KeyFactory.getInstance("RSA", "BC"); 
PrivateKey privateKey = keyFactory.generatePrivate(privSpec); 

我得到的代码例外。

com.android.org.bouncycastle.jcajce.provider.asymmetric.util.ExtendedInvalidKeySpecException: unable to process key spec: java.lang.IllegalArgumentException: unknown object in getInstance: com.android.org.bouncycastle.asn1.DERApplicationSpecific 
at com.android.org.bouncycastle.jcajce.provider.asymmetric.rsa.KeyFactorySpi.engineGeneratePrivate(KeyFactorySpi.java:105) 
at java.security.KeyFactory.generatePrivate(KeyFactory.java:186) 
at com.teknospire.ndasenda_agent.utils.Conversion.decryptUsingPrivateKey(Conversion.java:111) 
at com.teknospire.ndasenda_agent.utils.Conversion.getDecryptedSkey(Conversion.java:243) 
at com.teknospire.ndasenda_agent.json.JsonCreationAndExtraction.readLoginParams(JsonCreationAndExtraction.java:40) 
at com.mockUp.ndasenda.LoginActivity$LoginRequest.doInBackground(LoginActivity.java:283) 
at com.mockUp.ndasenda.LoginActivity$LoginRequest.doInBackground(LoginActivity.java:1) 
at android.os.AsyncTask$2.call(AsyncTask.java:288) 
at java.util.concurrent.FutureTask.run(FutureTask.java:237) 
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) 
at java.lang.Thread.run(Thread.java:848) 
Caused by: java.lang.IllegalArgumentException: unknown object in getInstance: com.android.org.bouncycastle.asn1.DERApplicationSpecific 
at com.android.org.bouncycastle.asn1.ASN1Sequence.getInstance(ASN1Sequence.java:50) 
at com.android.org.bouncycastle.asn1.ASN1Sequence.getInstance(ASN1Sequence.java:33) 
at com.android.org.bouncycastle.asn1.pkcs.PrivateKeyInfo.getInstance(PrivateKeyInfo.java:45) 
at com.android.org.bouncycastle.jcajce.provider.asymmetric.rsa.KeyFactorySpi.engineGeneratePrivate(KeyFactorySpi.java:91) 
... 12 more 
java.lang.NullPointerException 
at org.bouncycastle.crypto.params.KeyParameter.<init>(KeyParameter.java:13) 
at com.teknospire.ndasenda_agent.utils.Conversion.decryptUsingSessionKey(Conversion.java:145) 
at com.teknospire.ndasenda_agent.utils.Conversion.getDecryptionData(Conversion.java:185) 
at com.teknospire.ndasenda_agent.json.JsonCreationAndExtraction.readLoginParams(JsonCreationAndExtraction.java:41) 
at com.mockUp.ndasenda.LoginActivity$LoginRequest.doInBackground(LoginActivity.java:283) 
at com.mockUp.ndasenda.LoginActivity$LoginRequest.doInBackground(LoginActivity.java:1) 
at android.os.AsyncTask$2.call(AsyncTask.java:288) 
at java.util.concurrent.FutureTask.run(FutureTask.java:237) 
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) 
at java.lang.Thread.run(Thread.java:848) 

谁能帮我,如何读取从.cer文件的私钥。

在此先感谢。

+0

私钥有很多可能的格式;你的代码需要PKCS8格式,但你不会说'private_key.cer'的格式。 –

回答

0

检查this为基本实现从网站

Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); 

    byte[] input = new byte[] { (byte) 0xbe, (byte) 0xef }; 
    Cipher cipher = Cipher.getInstance("RSA/None/NoPadding", "BC"); 

    KeyFactory keyFactory = KeyFactory.getInstance("RSA", "BC"); 
    RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(new BigInteger(
     "12345678", 16), new BigInteger("11", 16)); 
    RSAPrivateKeySpec privKeySpec = new RSAPrivateKeySpec(new BigInteger(
     "12345678", 16), new BigInteger("12345678", 
     16)); 

    RSAPublicKey pubKey = (RSAPublicKey) keyFactory.generatePublic(pubKeySpec); 
    RSAPrivateKey privKey = (RSAPrivateKey) keyFactory.generatePrivate(privKeySpec); 

    cipher.init(Cipher.ENCRYPT_MODE, pubKey); 

    byte[] cipherText = cipher.doFinal(input); 
    System.out.println("cipher: " + new String(cipherText)); 

    cipher.init(Cipher.DECRYPT_MODE, privKey); 
    byte[] plainText = cipher.doFinal(cipherText); 
    System.out.println("plain : " + new String(plainText)); 
+0

感谢您的回应,但是这段代码会生成新的密钥,对吗?我已经有密钥可用,我只想知道如何从证书中读取私钥。 – venky

+0

检查您的问题是否与二进制编码有关。 http://newsgroups.derkeiler.com/Archive/Comp/comp.comp.lang.java.security/2006-01/msg00010.html – am110787

+0

是的,我不删除BEGIN-END标记,现在删除它们后,我获取异常java.security.spec.InvalidKeySpecException:java.lang.RuntimeException:错误:0D0680A8:asn1编码例程:ASN1_CHECK_TLEN:错误标记 – venky

0

代码从一个文件中获取私钥

摘录:

private KeyStore.PrivateKeyEntry getKeyFromFile(String keyStoreFile, 
    String Password, Context cntx) { 
    KeyStore.PrivateKeyEntry entry = null; 
    try { 
     AssetManager am = cntx.getAssets(); 
     char[] keyStorePassword = Password.toCharArray(); 
     // Load the KeyStore and get the signing key and certificate. 
     KeyStore ks = KeyStore.getInstance("PKCS12"); 

     ks.load(am.open(keyStoreFile), keyStorePassword); 
     String alias = ks.aliases().nextElement(); 

     Entry entry1 = ks.getEntry(alias, new KeyStore.PasswordProtection(
       keyStorePassword)); 
     entry = (KeyStore.PrivateKeyEntry) entry1; 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
    return entry; 
} 

可以解密使用下面的方法您的数据:

public byte[] decryptUsingPrivateKey(String encryptedData, Context cntx) { 

    byte[] utf8 = null; 
    try { 
     KeyStore.PrivateKeyEntry privateKey = getKeyFromFile(
       "PrivateKeyFile.pfx", "privatekeypassword", cntx); 

     Cipher rsa; 
     rsa = Cipher.getInstance("RSA/ECB/PKCS1Padding"); 
     rsa.init(Cipher.DECRYPT_MODE, privateKey.getPrivateKey()); 
     utf8 = rsa.doFinal(Base64.decode(encryptedData)); 

    } catch (Exception e) { 
     System.out.println(e); 
    } 

    return utf8; 
} 

注:

  1. 要使用这个,你必须编译库“bcprov-jdk15on-152.jar”在您的应用程序
  2. 在使用Android上的私钥文件是不是一个好的做法。希望你在测试服务器上使用它。
+0

感谢您的回应,我在使用代码时遇到异常java.security.KeyStoreException :java.security.NoSuchAlgorithmException:未找到KeyStore PKCS实现,.cer typr文件的算法是什么? – venky

+0

请尝试此链接:http://www.programcreek.com/java-api-examples/java.security.KeyStoreException。我将回到你的.cer类型文件。 –