gpt4 book ai didi

python - Google App Engine (Python) 中的 AES 加密和 iOS (Objective-C) 中的解密

转载 作者:太空宇宙 更新时间:2023-11-04 06:37:30 25 4
gpt4 key购买 nike

我正在尝试从 python (Google App Engine) 加密一些数据,然后在 iOS 上解密。

基于 AES 加密有很多选项以及 Python 和 Objective-C 中可用的不同格式这一事实,围绕此存在几个问题。

由于 PyCrypto 库在 Google App Engine 上的可用性有限,并且 iOS/Objective-C 端的 AES 代码需要 PKCS7Padding,我决定在 python 端使用 slowAES。

我还使用了 16 位 key 、CBC 模式和 PKCS7Padding。

鉴于此,这是我的加密函数和辅助变量/函数:

def str2nums(s):
return map(ord, s)

key = "hjt4mndfy234n5fs"
moo = aes.AESModeOfOperation()
iv = [12, 34, 96, 15] * 4
CBC_mode = moo.modeOfOperation['CBC']
nkey = str2nums(key)


def encrypt(plaintext):
funcName = inspect.stack()[0][3]
logging.debug("Enter " + funcName)
logging.debug("Input string: " + plaintext)
m, s, encData = moo.encrypt(plaintext, CBC_mode, nkey, len(nkey), iv)
fmt = len(encData)*'B'
dataAsStr = ""
for j in encData:
dataAsStr = dataAsStr + str(j) + ","
logging.debug("Output encrypted data:[" + dataAsStr + "]")
encoded = base64.b64encode(struct.pack(fmt, *encData))
logging.debug("Output encrypted string: " + encoded)
decoded = struct.unpack(fmt, base64.b64decode(encoded))
decrypted = moo.decrypt(decoded, s, CBC_mode, nkey, len(nkey), iv)
logging.debug("Output decrypted back: " + decrypted)
return encoded

请注意,在 Python 端,我对数据进行加密、打包,然后进行 base64 编码。在返回此加密数据之前,我还进行了解密测试,只是为了在日志中显示它确实有效。

在 iOS 端,我使用以下 AES NSData 添加:

- (NSData *)AES128DecryptWithKey:(NSString *)key {
// 'key' should be 16 bytes for AES128, will be null-padded otherwise
char keyPtr[kCCKeySizeAES128+1]; // room for terminator (unused)
bzero(keyPtr, sizeof(keyPtr)); // fill with zeroes (for padding)

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

NSUInteger dataLength = [self length];

//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(bufferSize);

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

if (cryptStatus == kCCSuccess) {
//the returned NSData takes ownership of the buffer and will free it on deallocation
return [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted];
}

free(buffer); //free the buffer;
return nil;
}

当我像这样提取 base64/打包/加密数据时,我正在使用它:

NSMutableString * result = [[NSMutableString alloc] initWithData:receivedData encoding:NSUTF8StringEncoding];
if (LOG) { NSLog(@"Base64 encoded / Encrypted string: %@", result); }

NSData* encryptedData = [NSData decodeBase64ForString:result]; // base64 decode

if (LOG) { NSLog(@"Encrypted string: %@", encryptedData); }

NSData* decryptedData = [encryptedData AES128DecryptWithKey:@"hjt4mndfy234n5fs"]; // AES Decrypt

问题是,我似乎无法在客户端 (iOS) 端正确解密数据,即使它在服务器上(在 python 中)解密得很好。

在解密过程中,cryptStatus 总是结束:kCCAlignmentError。我不太明白。

我也搞砸了 AES 256,但我认为我需要一个 32 位 key ,这似乎不是 CBC 模式下 slowAES 的选项(至少根据示例?)。

服务器的日志记录(注意实际未加密的数据只是一个空集 [] 。这是返回给客户端的 JSON 表示。

2012-01-04 08:48:13.962
Enter encrypt
D 2012-01-04 08:48:13.962
Input string: []
D 2012-01-04 08:48:13.967
Output encrypted data:[4,254,226,26,101,240,22,113,44,54,209,203,233,64,208,255,]
D 2012-01-04 08:48:13.967
Output encrypted string: BP7iGmXwFnEsNtHL6UDQ/w==
D 2012-01-04 08:48:13.971
Output decrypted back: []

客户端(iOS)的日志记录:

2012-01-04 12:45:13.891 Base64 encoded / Encrypted string: BP7iGmXwFnEsNtHL6UDQ/w==
2012-01-04 12:45:13.892 Encrypted string: <04fee21a 65f01671 2c36d1cb e940d0ff>
2012-01-04 12:45:29.126 Decrypted string:

所以我的问题是:

  1. “对齐错误”是什么意思?或者我做错了什么它不想在客户端解密?
  2. 考虑到数据看起来匹配得很好,我是否需要担心解包数据?如果是这样,我将如何处理 C 或 Objective-C 中的 unpack() 函数?
  3. 是否有更好的方法在 Google App Engine 和 iOS 之间进行 AES 加密?

编辑:我还应该注意到,除了使用相同初始化向量的答案外,我发现 python 和 iOS 代码之间的填充差异。加密/解密对于少量数据工作正常,但后来我遇到了无法用较大数据解密的情况。我通过将 iOS 端更改为不使用 PKCS7Padding 并将 0 放在那里来解决此问题。

最佳答案

IV 需要在两端匹配。

IV(初始化向量)是一串字节,通过加密器/解密器发送,以便在发送“真实”数据之前将其“内存”置于伪随机状态。由于加密结果取决于之前经过的过程,因此这种初始化使得恶意的第 3 方无法(不知道 IV)知道给定的明文和 key 是否可以生成给定的密文。

理想情况下,IV 本身在某种程度上是可变的,可能基于序列号或与密文一起发送的某些其他文本,或者基于在端点之间同步的计数器。

IV 的存在(即使是半可预测的)显着增加了使用“已知明文”攻击的难度。这对于相对较短、频繁的消息尤其重要。

关于python - Google App Engine (Python) 中的 AES 加密和 iOS (Objective-C) 中的解密,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8731920/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com