无法解密Objective C中的AES加密字符串

时间:2014-08-18 08:16:14

标签: android ios aes sha256 pkcs#7

我想在Android,IOS和PHP中加密和解密。

在android和PHP中使用

  • 加密类型:AES
  • 加密模式:CBC
  • 填充:PKCS7Padding
  • 哈希算法:SHA-256

当我在android上加密和解密时,它完美无缺。但是当我尝试解密处于Base64或Hex2Binary的IOS或PHP加密字符串时。在android上它解密字符串,但IOS案例的前16个字符和PHP代码的19个字符,它不会解密显示其他字符。我正在粘贴android代码

            // Ignore this line this is for encoding
            //String input = "Congratulation, You've sucessfully decoded!";

            final byte[] iv = new byte[16];
            Arrays.fill(iv, (byte) 0x00);
            IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);

            // When I tried with this its gives "pad block corrupted" exception else work as above i told

            /*byte[] key = CommonUtilities.encryptionKey.getBytes("UTF-8");
            System.out.println(key.length);
            MessageDigest sha = MessageDigest.getInstance("SHA-256");
            key = sha.digest(key);
            key = Arrays.copyOf(key, 16); // use only first 128 bit
            System.out.println(key.length);
            System.out.println(new String(key,"UTF-8"));
            SecretKeySpec secretKey = new SecretKeySpec(key, "AES");*/

            // encryptionKey = "12345678901234561234567890123456"; Same in IOS and PHP
            SecretKeySpec skeySpec = new SecretKeySpec(CommonUtilities.encryptionKey.getBytes("UTF-8"), "AES");
            Cipher ecipher = Cipher.getInstance("AES/CBC/PKCS7Padding");

            // Ignore these lines these are for encoding
            /*ecipher.init(Cipher.ENCRYPT_MODE, skeySpec, ivParameterSpec);
            byte[] dstBuff = ecipher.doFinal(input.getBytes("UTF-8"));              
            System.out.println("encrypted: " + new String(dstBuff, "UTF-8")); 
            String enbin2hex = com.byte2hex(dstBuff);    
            String en = Base64.encodeToString(dstBuff, Base64.DEFAULT);*/    


            // this is Hex2Binay that IOS gives me to decrypt
            // Original Text: "hello shani how are you doing , Stuck in encryption ?"
            String strBin2Hex = "30BEF4AB063D0D72F91D8D11A7ADEE1B1EC58F67C4D9CC20F59FB56B8B23B7C665198CFF805897BD1AFB82E578AC82C6C18C0EA909E17540D0B95A81E8446168";



            ecipher.init(Cipher.DECRYPT_MODE, skeySpec, ivParameterSpec);
            byte[] de = ecipher.doFinal(com.hex2Byte(strBin2Hex));  

            //de = removeTrailingNulls(de);
            //int bytesDecryptedAfter = de.length;

            System.out.println("decrypted: " + new String(de, "UTF-8"));
            // Decrypted String "igohj&t`hnh"kkr&are you doing , Stuck in encryption ?"

在这里,您可以看到无法解密完整字符串“hello shani how”缺少字符。

在IOS中使用

  • AES256
  • kCCOptionPKCS7Padding

    // IOS encrypt code
    - (NSData *)AES256EncryptWithKey:(NSString *)key {
    char keyPtr[kCCKeySizeAES256+1];     bzero(keyPtr, sizeof(keyPtr)); // fill with zeroes (for padding)
    
    
    
    
    // fetch key data
    [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
    
     NSUInteger dataLength = [self length];
    
     //See the doc: For block ciphers, the output size will always be less than or
     //equal to the input size plus the size of one block.
     //That's why we need to add the size of one block here
     size_t bufferSize = dataLength + kCCBlockSizeAES128;
     void *buffer = malloc(bufferSize);
    
     size_t numBytesEncrypted = 0;
     CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding,
                                      keyPtr, kCCKeySizeAES256,
                                      "0000000000000000" /* initialization vector (optional) */,
                                      [self bytes], dataLength, /* input */
                                      buffer, bufferSize, /* output */
                                      &numBytesEncrypted);
     if (cryptStatus == kCCSuccess) {
         //the returned NSData takes ownership of the buffer and will free it on deallocation
         return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
     }
    
     free(buffer); //free the buffer;
     return nil;
     }
    

知道我做错了什么。

谢谢你的时间

1 个答案:

答案 0 :(得分:3)

我看到了问题:

  • 在iOS
  • 上未指定密码模式(Android代码中的CBC)
  • 算法在iOS(AES128)上明确指定,而不在Android
  • 上指定
  • 算法不符合iOS 128/256上的密钥大小。
  • 初始向量不同

所以,而不是

CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding,
                                  keyPtr, kCCKeySizeAES256,
                                  "0000000000000000" /* initialization vector (optional) */,
                                  [self bytes], dataLength, /* input */
                                  buffer, bufferSize, /* output */
                                  &numBytesEncrypted);
 if (cryptStatus == kCCSuccess) {
     //the returned NSData takes ownership of the buffer and will free it on deallocation
     return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
 }

我会尝试

char iv[kCCBlockSizeAES128 + 1]; bzero(iv, sizeof(iv))
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES, kCCOptionPKCS7Padding,
                                  keyPtr, kCCKeySizeAES128,
                                  iv,
                                  [self bytes], dataLength, /* input */
                                  buffer, bufferSize, /* output */
                                  &numBytesEncrypted);
 if (cryptStatus == kCCSuccess) {
     //the returned NSData takes ownership of the buffer and will free it on deallocation
     return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
 }

确保Android也使用AES128