2017-08-01 139 views
-1

我需要轉換在我們的服務器端加密/解密方法如下,請檢查下面的代碼AESCrypt加密/解密從PHP到iOS

------------------------------------------------------------------------------------------------------------------------------------- 
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC); 
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND); 
$key = "a16byteslongkey!"; 
$plaintext = "iphone"; 
$ciphertext = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $plaintext, MCRYPT_MODE_CBC, $iv); 


$ciphertext = base64_encode($ciphertext); 
echo "ciphertext: ".$ciphertext."<br/>"; 

$ciphertextinput = base64_decode($ciphertext); 
$cipherdetext = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $ciphertextinput, MCRYPT_MODE_CBC, $iv); 
echo "decryptText:".$cipherdetext."<br/>"; 

我使用AES 256加密嘗試,但它提供了不同的結果,

加密

- (NSData *)AES256EncryptWithKey:(NSString *)key { 
// 'key' should be 32 bytes for AES256, will be null-padded otherwise 
char keyPtr[kCCKeySizeAES256+1]; // room for terminator (unused) 
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, 
             NULL /* 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;} 

解密

- (NSData *)AES256DecryptWithKey:(NSString *)key { 
// 'key' should be 32 bytes for AES256, will be null-padded otherwise 
char keyPtr[kCCKeySizeAES256+1]; // room for terminator (unused) 
bzero(keyPtr, sizeof(keyPtr)); // fill with zeroes (for padding) 

// fetch key data 
[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding]; 

char ivPtr = ""; 

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 numBytesDecrypted = 0; 
CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding, 
             keyPtr, kCCKeySizeAES256, 
             NULL /* initialization vector (optional) */, 
             [self bytes], dataLength, /* input */ 
             buffer, bufferSize, /* output */ 
             &numBytesDecrypted); 

if (cryptStatus == kCCSuccess) { 
    //the returned NSData takes ownership of the buffer and will free it on deallocation 
    return [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted]; 
} 

free(buffer); //free the buffer; 
return nil;} 

OriginalText:iphone

密文:SXNepKfh0IrlDDdkq4EdmQ ==

請告訴我錯在這裏,請給從PHP解密加密文本的一些建議。如何從base 64編碼字符串得到確切的「iphone」字符串SXNepKfh0IrlDDdkq4EdmQ ==

另外,請讓我知道如何在AES加密中使用ECB模式。

謝謝!

+0

作爲一個** **測試**在沒有**'kCCOptionPKCS7Padding'的情況下在iOS **中解密,以十六進制記錄結果(將其添加到問題中),查看最後一個字節,如果解密是正確的。注意:Base64非常適合**計算機**,但不適用於人,因爲它使用十六進制表示字節。 – zaph

+0

這個問題需要一個[MCVE]完整的測試值輸入和輸出在十六進制適當的地方。 – zaph

回答

1

問題:

`mcrypt的使用非標準空數據填充,iOS的代碼使用PKCS#7填充。

的修復,三種選擇:

  1. 使用PKCS#7填充,mcrypt的7填充添加PKCS#加密之前和解密之後將其刪除。 (推薦)

  • 用NULL填充,公共的密碼不指定kCCOptionPKCS7Padding,空填充加密之前添加和解密之後除去。 (不推薦)
  • 它最好不要用的mcrypt,它是放棄的,並沒有在年被更新,並且不支持標準PKCS#7 (néePKCS#5)填充,只有非標準的null填充甚至不能用於二進制數據。 mcrypt有許多優秀的bugs追溯到2003年。不推薦使用mcrypt擴展名將在PHP 7.2中刪除。請考慮使用defuseRNCryptor,他們提供了一個完整的解決方案,並且正在維護和正確。
  • +0

    好的,謝謝!將嘗試所有三個選項。我相信,RNCryptor現在是最好的。 – Gopik

    +0

    使用null填充,對於Common Crypto,不指定kCCOptionPKCS7Padding,在加密之前添加null填充並在解密後刪除。 (不推薦) - 所以我們需要在CCCrypt中傳遞nil而不是kCCOptionPKCS7Padding選項? 它崩潰的應用程序,似乎輸入密鑰長度錯誤。 ***由於未捕獲的異常'InputAlignmentException'而終止應用程序,原因是:'輸入大小未正確對齊。' – Gopik

    +0

    密鑰必須完全是AES大小,128,192或256位,並且對於必須指定大小的Common Crypto。在你的代碼中你有'kCCKeySizeAES256'是的關鍵是''a16byteslongkey!'',它是16字節/ 128位,兩者不匹配。 **添加測試值:在十六進制輸入和輸出二進制,而不是Base64 **,你必須做你的一部分。 – zaph