英文:
Decrypting data with CCCryptor in Objective-C that was encrypted with CFB in Go
问题
我已经在这个项目上工作了很长时间,但是卡住了。
我正在编写一个iOS应用程序,它从Go服务器端应用程序接收AES加密数据并进行解密。我在iOS端使用CCCryptor进行解密。然而,无论如何,我都无法得到明文。有一个可工作的Java/Android实现,它在Go端解密得很好,所以我相信问题出在我的CCCryptor设置上。
实际上,我在解密时得到了一个成功状态为0,但是将输出进行NSString initWithBytes操作后得到了一个空字符串。
注意:我只在编写iOS端的代码。
Go代码进行加密:
func encrypt(key, text []byte) []byte {
block, err := aes.NewCipher(key)
if err != nil {
panic(err)
}
b := encodeBase64(text)
ciphertext := make([]byte, aes.BlockSize+len(b))
iv := ciphertext[:aes.BlockSize]
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
panic(err)
}
cfb := cipher.NewCFBEncrypter(block, iv)
cfb.XORKeyStream(ciphertext[aes.BlockSize:], []byte(b))
return ciphertext
}
Objective-C代码进行解密
+ (NSData *)decrypt:(NSData*)data withPassword:(NSString*)password{
NSData * key =
;
size_t dataLength = [data length] - kCCBlockSizeAES128;
NSData *iv = [data subdataWithRange:NSMakeRange(0, kCCBlockSizeAES128)];
NSData *encrypted = [data subdataWithRange:NSMakeRange(kCCBlockSizeAES128, dataLength)];
//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(dataLength);
NSMutableData *ret = [NSMutableData dataWithLength:dataLength + kCCBlockSizeAES128];
size_t numBytesDecrypted = 0;
CCCryptorStatus status = CCCrypt(kCCDecrypt, kCCAlgorithmAES,
0x0000, // change to 0 solve the problem
[key bytes],
kCCKeySizeAES256,
[iv bytes],
[encrypted bytes], dataLength, /* input */
[ret mutableBytes], [ret length], /* output */
&numBytesDecrypted
);
NSLog(@"err: %d", status);
NSLog(@"dataLength: %d, num: %d", (int)dataLength, (int)numBytesDecrypted);
if (status == kCCSuccess) {
//the returned NSData takes ownership of the buffer and will free it on deallocation
return ret;
}
// free(buffer); //free the buffer;
return nil;
}
英文:
I've been working on this for a long time, but am stuck.
I'm writing an iOS app that takes AES encrypted data form a Go server-side application and decrypts it. I'm using CCCryptor for the decryption on the iOS side. However, I cannot, for the life of me, get plaintext out. There is a working Java/Android implementation, and it decrypts fine on the Go side, so I'm pretty sure it's to do with my CCCryptor settings.
I'm actually getting a 0 success status on decryption, but taking the output and doing a NSString initWithBytes gives me a null string.
Note: I'm only writing the iOS side.
Go code that encrypts:
func encrypt(key, text []byte) []byte {
block, err := aes.NewCipher(key)
if err != nil {
panic(err)
}
b := encodeBase64(text)
ciphertext := make([]byte, aes.BlockSize+len(b))
iv := ciphertext[:aes.BlockSize]
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
panic(err)
}
cfb := cipher.NewCFBEncrypter(block, iv)
cfb.XORKeyStream(ciphertext[aes.BlockSize:], []byte(b))
return ciphertext
}
Objective-C code that decrypts
+ (NSData *)decrypt:(NSData*)data withPassword:(NSString*)password{
NSData * key =
;
size_t dataLength = [data length] - kCCBlockSizeAES128;
NSData *iv = [data subdataWithRange:NSMakeRange(0, kCCBlockSizeAES128)];
NSData *encrypted = [data subdataWithRange:NSMakeRange(kCCBlockSizeAES128, dataLength)];
//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(dataLength);
NSMutableData *ret = [NSMutableData dataWithLength:dataLength + kCCBlockSizeAES128];
size_t numBytesDecrypted = 0;
CCCryptorStatus status = CCCrypt(kCCDecrypt, kCCAlgorithmAES,
0x0000, // change to 0 solve the problem
[key bytes],
kCCKeySizeAES256,
[iv bytes],
[encrypted bytes], dataLength, /* input */
[ret mutableBytes], [ret length], /* output */
&numBytesDecrypted
);
NSLog(@"err: %d", status);
NSLog(@"dataLength: %d, num: %d", (int)dataLength, (int)numBytesDecrypted);
if (status == kCCSuccess) {
//the returned NSData takes ownership of the buffer and will free it on deallocation
return ret;
}
// free(buffer); //free the buffer;
return nil;
}
答案1
得分: 1
我的建议是使用RNCryptor,它提供了iOS和Go的实现。
RNCryptor包含了您所需的所有密码学原语,包括:
- AES-256加密(高级加密标准)
- CBC模式(密码块链)
- 使用PBKDF2进行密码拉伸(基于密码的密钥派生函数2)
- 密码盐
- 随机初始化向量(IV)
- 先加密后哈希的HMAC(身份验证)
它已经广泛部署和验证。
在密码学方面很容易出错,使用RNCryptor可以避免潜在的陷阱。
如果我有您所需的密码学需求,我会使用它。
英文:
My recommendation is to use RNCryptor, there is an iOS and a Go implementation available.
RNCryptor combines all the necessary cryptographic primitives for your needs including:
- AES-256 encryption (Advanced Encryption Standard)
- CBC mode (Cipher Block Chaining)
- Password stretching with PBKDF2 (Password Based Key Derivation Function 2)
- Password salting
- Random IV (Initialization Vector)
- Encrypt-then-hash HMAC (Authentication)
It has been extensively deployed and vetted.
It is all to easy to get cryptography wrong and using RNCryptor will avoid the potential pitfalls.
If I had the cryptographic needs you have I would use it.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论