Iphone 在IOS中实现AES256加密

Iphone 在IOS中实现AES256加密,iphone,encryption,aes,nsdata,commoncrypto,Iphone,Encryption,Aes,Nsdata,Commoncrypto,这是我的java代码。现在我想在Objective-C中实现相同的功能 密码加密; IvParameterSpec iv=新的IvParameterSpec(键); SecretKeySpec skeySpec=新SecretKeySpec(键,“AES”); encryptCipher=Cipher.getInstance(“AES/CBC/PKCS5Padding”); encryptCipher.init(Cipher.ENCRYPT_模式,skeySpec,iv); byte[]encr

这是我的java代码。现在我想在Objective-C中实现相同的功能

密码加密;
IvParameterSpec iv=新的IvParameterSpec(键);
SecretKeySpec skeySpec=新SecretKeySpec(键,“AES”);
encryptCipher=Cipher.getInstance(“AES/CBC/PKCS5Padding”);
encryptCipher.init(Cipher.ENCRYPT_模式,skeySpec,iv);
byte[]encrypted=encryptCipher.doFinal(dataToEncrypt.getBytes());
Log.d(“标记”,“加密字符串:”
+Base64.encodeToString(加密,Base64.DEFAULT));
返回Base64.encodeToString(加密,Base64.DEFAULT).trim();
这是我的iOS实现

-(NSData*)AES256EncryptWithKey:(NSString*)密钥
{
char-keyPtr[kCCKeySizeAES256+1];
bzero(keyPtr,sizeof(keyPtr));
[key-getCString:keyPtr-maxLength:sizeof(keyPtr)编码:NSUTF8StringEncoding];
NSU整数数据长度=[自身长度];
size\u t bufferSize=dataLength+kccblocksizeaaes128;
void*buffer=malloc(bufferSize);
大小\u t numBytesEncrypted=0;
CCCryptorStatus cryptStatus=CCCrypt(kCCEncrypt,
KCcalGorithmae128,
KCCOPIONPKCS7填充,
钥匙,
kCCKeySizeAES256,
无效的
[自身字节],
数据长度,
缓冲器
缓冲区大小,
&(未加密);
if(cryptStatus==kCCSuccess)
{
返回[NSData DATAFTHBYTESNOCOPY:缓冲区长度:numBytesEncrypted];
}
自由(缓冲);
返回零;
}
这是我的哈希键生成函数。此函数在android和ios中返回相同的密钥

int dkLen = 16;
    NSData *keyData = [hash_key dataUsingEncoding:NSUTF8StringEncoding];
    NSData *salt    = [saltKey dataUsingEncoding:NSUTF8StringEncoding];
    uint    rounds  = 1000;
    uint    keySize = kCCKeySizeAES128;

    NSMutableData *derivedKey = [NSMutableData dataWithLength:keySize];





    CCKeyDerivationPBKDF(kCCPBKDF2,               // algorithm
                         keyData.bytes,           // password
                         keyData.length,          // passwordLength
                         salt.bytes,              // salt
                         salt.length,             // saltLen
                         kCCPRFHmacAlgSHA1,       // PRF
                         rounds,                  // rounds
                         derivedKey.mutableBytes, // derivedKey
                         dkLen*8);
 return derivedKey;

我得到了不同的输出。我做错了什么?请帮我查一下。

好吧,你的钥匙有多大
kCCAlgorithmAES128
kCCKeySizeAES256
采用不同的密钥大小。我假设您使用的是一个16字节的密钥,因为您的Java代码会抛出一个异常。如果您使用的是128位密钥,则应使用
kCCKeySizeAES128

此外,您没有传入任何IV,因此假设IV中填充了0x00字节,但在Java中,您将密钥用作IV

不要将密钥用作IV。这会减少对IV的使用,因为IV首先是用来随机化密文的。您需要为每个加密生成一个随机IV,并将其与密文一起发送,例如,将其预先添加到密文中


是的。

一个问题是Java代码使用CBC模式,iOS代码使用ECB模式

接下来,从引用的项目:
//result=yhbhapwtpq297akf/g==

Base64无效,它不包含4字节的倍数

使用这些选项:CBC、PKCS#7填充

inputs: data in: "hello" which will be null padded to the block length of 16-bytes key: base64: VQQhu+dUdqXGoE7RZL2JWg== hex: 550421bbe75476a5c6a04ed164bd895a iv: base64: VQQhu+dUdqXGoE7RZL2JWg== hex: 550421bbe75476a5c6a04ed164bd895a encrypted output: hex: ff21db840a704e943666113dec0285fe base64: /yHbhApwTpQ2ZhE97AKF/g== 这是加密方法(在类
TestClass
中):

注意:我将加密和数据转换分开。将它们混为一谈只会使测试更加复杂

如果使用在线加密实现,填充可能不是PKCS#7,因为mcrypt不支持它,而是非标准的空填充。由于pad字节只是pad字节的计数,因此可以在输入中模拟padding。下面是一个使用

请注意,填充为16字节块大小的“hello”PKCS#7会添加11个字节的uint8值11或
0x0B
68656c6c6c6f0b0b0b


最后一个问题是,为什么Java代码不产生这个结果?

因此,它是一个128位的密钥(假设base64编码)。如果你想使用AES-256,那么你需要一个更大的密钥,这样你就不能在Java中直接使用该密钥作为IV。我检查了来自android和ios的两个密钥。sameI从未说过你的密钥有错。我说你在Java和Obj-C中使用了不同的IVs。你能提供一个示例代码吗?因为我是iOS@Artjom B的新手,我无法修复它,因为你似乎仍然有问题,你可以进一步改进这个问题:(1)显示两个版本的输入和输出(十六进制);(2) 在你喜欢的在线IDE中提供可运行的代码片段,比如(它支持Java和Objective-C)。你能给我一些类似的例子吗@Artjom B,你的帮助是值得赞赏的。请看这个谢谢扎夫。我有一个java和c语言的工作实现,它工作得很好。为了实现互操作性,只需获得相同的所有输入即可。结合了许多操作的库的一个问题是,它们通常不记录内部内容,这使得互操作性变得困难。有额外的事情发生。也许字符串不是UTF-8?这就是为什么我保持实际的加密简单,只是数据字节,然后在加密之外添加数据转换。通过使用十六进制转储,我可以准确地看到数据是什么。一个区别是密钥大小,在iOS代码中,它们的密钥被显式指定为256位(32字节),但Java代码根据提供的密钥数据选择密钥大小,即128位(16字节)。另一种可能是数据(“hello”)由unichar(16位)组成。我们在我的all项目中使用这种方法,所以目前我无法改进。APH解密提供不同的输出
NSString *base64Key  = @"VQQhu+dUdqXGoE7RZL2JWg==";
NSString *dataString = @"hello";

NSData *key  = [[NSData alloc] initWithBase64EncodedString:base64Key  options:0];
NSData *data = [dataString dataUsingEncoding:NSUTF8StringEncoding];

NSLog(@"key:  %@", key);
NSLog(@"data: %@", data);

NSData *encryptedData = [TestClass crypt:data
                                 iv:key
                                key:key
                            context:kCCEncrypt];

NSLog(@"encryptedData: %@", encryptedData);
NSString *encryptedBase64Data = [encryptedData base64EncodedStringWithOptions:0];
NSLog(@"encryptedBase64Data: %@", encryptedBase64Data);
+ (NSData *)crypt:(NSData *)dataIn
                  iv:(NSData *)iv
                 key:(NSData *)symmetricKey
             context:(CCOperation)encryptOrDecrypt
{
    CCCryptorStatus ccStatus   = kCCSuccess;
    size_t          cryptBytes = 0;    // Number of bytes moved to buffer.
    NSMutableData  *dataOut    = [NSMutableData dataWithLength:dataIn.length + kCCBlockSizeAES128];

    ccStatus = CCCrypt( encryptOrDecrypt,
                       kCCAlgorithmAES128,
                       kCCOptionPKCS7Padding,
                       symmetricKey.bytes,
                       kCCKeySizeAES128,
                       iv.bytes,
                       dataIn.bytes,
                       dataIn.length,
                       dataOut.mutableBytes,
                       dataOut.length,
                       &cryptBytes);

    if (ccStatus != kCCSuccess) {
        NSLog(@"CCCrypt status: %d", ccStatus);
    }

    dataOut.length = cryptBytes;

    return dataOut;
}