Iphone 在IOS中实现AES256加密
这是我的java代码。现在我想在Objective-C中实现相同的功能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
密码加密;
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;
}