2010-09-13 171 views
4

我在我的android应用程序上生成了一对RSA密钥。RSA和AES解密和加密问题

我从网络服务接收 - AES密钥,使用我的RSA公钥 加密 - 使用AES密钥编码的字符串。

所以我必须做到以下几点: - 解密AES密钥 - 用获得的AES密钥解密字符串。

要生成的RSA密钥我所做的:

keyGen = KeyPairGenerator.getInstance("RSA"); 
    keyGen.initialize(size); 
    keypair = keyGen.genKeyPair(); 
    privateKey = keypair.getPrivate(); 
    publicKey = keypair.getPublic(); 

在RSA解密我用:

public static byte[] decryptRSA(PrivateKey key, byte[] text) throws Exception 
     { 
      byte[] dectyptedText = null; 

      Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); 
      cipher.init(Cipher.DECRYPT_MODE, key); 
      dectyptedText = cipher.doFinal(text); 
      return dectyptedText; 
     } 

在AES解密我用:

public static byte[] decryptAES(byte[] key, byte[] text) throws Exception { 
      SecretKeySpec skeySpec = new SecretKeySpec(key, "AES"); 
      Cipher cipher = Cipher.getInstance("AES/ECB/PKCS1Padding"); 
      cipher.init(Cipher.DECRYPT_MODE, skeySpec); 
      byte[] decrypted = cipher.doFinal(text); 
      return decrypted; 
     } 

所以,在我的代码,以获得解密的AES密钥I do

byte[] decryptedAESKey = sm.decryptRSA(key, Base64.decode(ReceivedBase64EncryptedAESKey)); 
byte[] decryptedString = sm.decryptAES(decryptedAESKey, Base64.decode(ReceivedEncryptedAESString)); 

最后,我得到一个null为decryptedString。 我在做什么错?

回答

2

那么,事情是,解密的关键是8个字节长,我不得不让16个字节是兼容的AES 128位

所以,我做了一个方法将其转换回

private static byte[] GetKey(byte[] suggestedKey) 
     { 
      byte[] kRaw = suggestedKey; 
      ArrayList<Byte> kList = new ArrayList<Byte>(); 

      for (int i = 0; i < 128; i += 8) 
      { 
       kList.add(kRaw[(i/8) % kRaw.length]); 
      } 

      byte[] byteArray = new byte[kList.size()]; 
      for(int i = 0; i<kList.size(); i++){ 
      byteArray[i] = kList.get(i); 
      } 
      return byteArray; 
     } 

而且改写解密方法:

public static byte[] decryptAES(byte[] key, byte[] text) throws Exception { 

      SecretKeySpec skeySpec = new SecretKeySpec(GetKey(key), "AES"); 

      Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding","BC"); 

      byte [] iv = new byte[cipher.getBlockSize()]; 
      for(int i=0;i<iv.length;i++)iv[i] = 0; 
      IvParameterSpec ivSpec = new IvParameterSpec(iv); 
      cipher.init(Cipher.DECRYPT_MODE, skeySpec, ivSpec); 

      byte[] decrypted = cipher.doFinal(text); 
      return decrypted; 
     } 
0

我不知道你使用的是什么语言或库(看起来像Java?),但有些真的东西一般尝试:

  1. 你获取的加密字符串,好吗?检查ReceivedEncryptedAESString的长度和Base64.decode的输出以检查它们是否正常。
  2. AES解密不能失败,所以它必须是库初始化中的一个问题。在构建步骤和init步骤之后检查cipher的值/状态。
  3. 尝试一个更简单的测试用例:忽略RSA加密,并尝试使用您的Cipher对象解密某些内容。
+0

我使用的Android,其包含的库。 1.看起来不错,例如我收到ReceivedEncryptedAESString = qjYcPCHkFpbTjntDCpXCGabSY5DFH ...并且解密的AES密钥看起来像:[121,98,51,100,108,112,118,107,118,97] – Alin 2010-09-13 15:50:35

+0

2.问题似乎是在cipher.init(Cipher.DECRYPT_MODE,skeySpec);因为它引发一个异常:InvalidKeyException:密钥长度不是128/192/256位。也许我做RSA解密是错误的? – Alin 2010-09-13 16:00:55

+1

关键数组有多长?它可能太短(小于128位),需要某种填充,或者它太长,需要截断。 AES仅在这三种密钥长度上定义。由于这是从Web服务中检索的字符串,因此您需要找出错误长度的原因。也许从Web服务的消息被截断? – Amoss 2010-09-15 17:54:48