【问题标题】:Encrypt string with AES in Python and IOS在 Python 和 IOS 中使用 AES 加密字符串
【发布时间】:2015-09-16 14:41:16
【问题描述】:

我正在尝试在带有 CCCrypt 的 IOS 和带有 Crypto 的 Python 中使用 AES 加密字符串。但是我似乎得到了不同的结果。有人知道为什么吗?

我正在尝试使用带有 null IV 和 CBC 的 256 位 AES。

Python 代码:

key = 'verysecretkey1111111111111111111'

IV = 16 * '\x00'    
mode = AES.MODE_CBC
cipher = AES.new(key, AES.MODE_CBC, IV)

y='aaaabbbbccccdddd'
length = 16 - (len(y) % 16)
y += chr(length)*length

encoded = cipher.encrypt(y)
print base64.b64encode(encoded)

结果是 gyL9jv7bTgLz8xZQx/GLYNVnVrrwo6pLsc5Ew4Vl8Uk=

目标 C 代码

char keyPtr[kCCKeySizeAES256 ];
bzero( keyPtr, sizeof( keyPtr ) );

// fetch key data
[key getCString:keyPtr maxLength:sizeof( keyPtr  encoding:NSUTF8StringEncoding];

NSUInteger dataLength = [self length];


size_t bufferSize = dataLength + kCCBlockSizeAES128;
void *buffer = malloc( bufferSize );

size_t numBytesEncrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt( kCCEncrypt, kCCAlgorithmAES128,   kCCOptionPKCS7Padding,
                                      keyPtr, kCCKeySizeAES256,
                                      NULL /* initialization vector (optional) */,
                                      [self bytes], dataLength, /* input */
                                      buffer, bufferSize, /* output */
                                      &numBytesEncrypted );

结果是 DskVKDMGxFWLGSYszL/mEersVv9zq9PK9bPIV5UgLbs=

【问题讨论】:

  • 这不是您在这里拥有的完整代码。在 Obj-C 中如何提供密钥和数据?
  • 您是否有可能使用不同的静脉输液?我不是一个密码学家,但看起来你可能在 Python 代码中使用一系列 NULL 字节作为你的 IV(你可能想要 None?)并且在 ObjC 代码中你实际上是在传递 NULL - CCCrypt 如何处理这个问题?我也不确定 ObjC 代码中的操作模式应该是什么。它是 Python 代码中的 CBC,所以这也可能会影响它。
  • Common Crypto 对 iv 使用空值,因为 iv 被指定为 NULL (0x00)。由于该方法是扩展,因此未显示要加密的字符串,遗憾的是没有提到扩展的类现在是 Base64 编码 CCCrypt 输出的方法。似乎使用了扩展,因为它们是“闪亮的”,而“闪亮”吸引了知道的开发人员。

标签: python objective-c encryption aes pycrypto


【解决方案1】:

调用Objective-C方法有问题,给不完整的代码理解错误很难。

问题中的这句话绝对不正确:

[key getCString:keyPtr maxLength:sizeof( keyPtr  encoding:NSUTF8StringEncoding];

有两个问题:
1. sizeof 缺少右括号。
2.必须为“C”字符串要求的尾随空保留空间:

char keyPtr[kCCKeySizeAES256+1];  
bzero( keyPtr, sizeof(keyPtr));
[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSASCIIStringEncoding];

请注意,getCString: 方法返回状态但未检查,如果存在则错误将很明显。错误状态是开发者最好的朋友。

但如下面的代码所示,有一种更简单的方法来处理密钥。

这是一个结果与 Python 代码匹配的示例"

NSString *key  = @"verysecretkey1111111111111111111";
NSString *data = @"aaaabbbbccccdddd";

NSData *dataIn  = [data dataUsingEncoding:NSUTF8StringEncoding];
NSData *keyData = [key  dataUsingEncoding:NSUTF8StringEncoding];

CCCryptorStatus ccStatus   = kCCSuccess;
size_t          cryptBytes = 0;
NSMutableData  *dataOut    = [NSMutableData dataWithLength:dataIn.length + kCCBlockSizeAES128];

ccStatus = CCCrypt( kCCEncrypt,
                   kCCAlgorithmAES128,
                   kCCOptionPKCS7Padding,
                   keyData.bytes, kCCKeySizeAES256,
                   NULL,
                   dataIn.bytes, dataIn.length,
                   dataOut.mutableBytes, dataOut.length,
                   &cryptBytes);

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

NSString *objcEncrypted = [dataOut base64EncodedStringWithOptions:0];
NSLog(@"objcEncrypted: %@", objcEncrypted);

输出:

objcEncrypted:gyL9jv7bTgLz8xZQx/GLYNVnVrrwo6pLsc5Ew4Vl8Uk=

【讨论】:

  • 谢谢。我不知何故错过了检查终止的NULL。 惭愧
猜你喜欢
  • 1970-01-01
  • 2013-09-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-04
  • 2018-11-02
  • 1970-01-01
  • 2015-04-21
相关资源
最近更新 更多