douba9776 2015-09-21 03:25
浏览 28
已采纳

在Go语言中使用CFB加密的Objective-C中的CCCryptor解密数据

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 = [password dataUsingEncoding:NSUTF8StringEncoding];

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条回答 默认 最新

  • doucaishou0074 2015-09-21 15:17
    关注

    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.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 stm32开发clion时遇到的编译问题
  • ¥15 如何用Labview在myRIO上做LCD显示?(语言-开发语言)
  • ¥15 Vue3地图和异步函数使用
  • ¥15 C++ yoloV5改写遇到的问题
  • ¥20 win11修改中文用户名路径
  • ¥15 win2012磁盘空间不足,c盘正常,d盘无法写入
  • ¥15 用土力学知识进行土坡稳定性分析与挡土墙设计
  • ¥70 PlayWright在Java上连接CDP关联本地Chrome启动失败,貌似是Windows端口转发问题
  • ¥15 帮我写一个c++工程
  • ¥30 Eclipse官网打不开,官网首页进不去,显示无法访问此页面,求解决方法