使用Objective-C中的CCCryptor解密使用Go中的CFB加密的数据。

huangapple go评论85阅读模式
英文:

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.

huangapple
  • 本文由 发表于 2015年9月21日 11:25:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/32686871.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定