使用Objective-C和Decrypt在Python中加密数据

时间:2015-09-08 14:11:54

标签: python objective-c encryption aes

我遇到与this question相同的问题,但遗憾的是没有答案。

我有以下使用CCCrypt加密的Objective-c代码:

(NSData *)doCrypt:(NSData *)data usingKey:(NSData *)key withInitialVector:(NSData *)iv mode:(int)mode error: (NSError *)error
{
    int buffersize = 0;
    if(data.length % 16 == 0) { buffersize = data.length + 16; }
    else { buffersize = (data.length / 16 + 1) * 16 + 16; }

    // int buffersize = (data.length <= 16) ? 16 : data.length;
    size_t numBytesEncrypted = 0;
    void *buffer = malloc(buffersize * sizeof(uint8_t));
    CCCryptorStatus result = CCCrypt(mode, 0x0, 0x1, [key bytes], [key length], [iv bytes], [data bytes], [data length], buffer, buffersize, &numBytesEncrypted);

    return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted freeWhenDone:YES];
}

我使用kCCAlgorithmAES128kCCOptionPKCS7Padding作为选项,并使用[Cryptor doCrypt:data usingKey:key withInitialVector:nil mode:0x0 error:nil];

调用该函数

现在我想用python解密它,为此我有以下代码:

def decrypt(self, data, key):
        iv = '\x00' * 16

        encoder = PKCS7Encoder()
        padded_text = encoder.encode(data)

        mode = AES.MODE_CBC
        cipher = AES.new(key, mode, iv)
        decoded = cipher.decrypt(padded_text)
        return decoded

PKCS7Encoder看起来像这样:

class PKCS7Encoder():
    """
    Technique for padding a string as defined in RFC 2315, section 10.3,
    note #2
    """
    class InvalidBlockSizeError(Exception):
        """Raised for invalid block sizes"""
        pass

    def __init__(self, block_size=16):
        if block_size < 2 or block_size > 255:
            raise PKCS7Encoder.InvalidBlockSizeError('The block size must be ' \
                    'between 2 and 255, inclusive')
        self.block_size = block_size

    def encode(self, text):
        text_length = len(text)
        amount_to_pad = self.block_size - (text_length % self.block_size)
        if amount_to_pad == 0:
            amount_to_pad = self.block_size
        pad = chr(amount_to_pad)
        return text + pad * amount_to_pad

    def decode(self, text):
        pad = ord(text[-1])
        return text[:-pad]

然而,每当我调用decrypt()函数时,它都会返回垃圾。我错过了什么或在某处启用了错误的选项吗?

示例输入:

NSData *keyData = [[NSData alloc] initWithRandomData:16];
    NSLog(@"key: %@", [keyData hex]);
    NSString *str = @"abcdefghijklmno";
    NSLog(@"str: %@", str);
    NSData *encrypted = [Cryptor encrypt:[str dataUsingEncoding:NSUTF8StringEncoding] usingKey:keyData];
    NSLog(@"encrypted str: %@", [encrypted hex]);

给出:

key: 08b6cb24aaec7d0229312195e43ed829
str: a
encrypted str: 52d61265d22a05efee2c8c0c6cd49e9a

和python:

cryptor = Cryptor()
encrypted_hex_string = "52d61265d22a05efee2c8c0c6cd49e9a"
hex_key = "08b6cb24aaec7d0229312195e43ed829"
print cryptor.decrypt(encrypted_hex_string.decode("hex"), hex_key.decode("hex"))

结果:

láz

这很奇怪,但是如果转储十六进制我得到610f0f0f0f0f0f0f0f0f0f0f0f0f0f0fb02b09fd58cccf04f042e2c90d6ce17a61 = a所以我认为它只是显示错误。

更大的投入:

key: 08b6cb24aaec7d0229312195e43ed829
str: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
encrypted str: 783fce3eca7ebe60d58b01da3d90105a93bf2d659cfcffc1c2b7f7be7cc0af4016b310551965526ac211f4d6168e3cc5

结果:

aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaôNÍ“ƒ˜�Üšw6C%

在这里你看到a'被打印出垃圾...所以我认为这是一个填充错误或类似的东西

IV在iOs方面是nill,在Python方面是16x 0(参见代码)

1 个答案:

答案 0 :(得分:2)

您的解密: aes_decrypt(pkcs7_pad(ciphertext))
正确解密: pkcs7_unpad(aes_decrypt(ciphertext))

必须以这种方式完成,因为CBC模式下的AES需要块大小的倍数的明文,但是您通常希望加密任意明文。因此,您需要在加密前应用填充并在解密后删除填充。

请注意,对于a - (b % a)a的任何(正)值,b不能为0。这意味着

if amount_to_pad == 0:
    amount_to_pad = self.block_size

是无法访问的代码,可以删除。好的是,a - (b % a)已经完成了你想对if块做的事情。

您还应该扩展unpad(decode)函数以实际检查每个填充字节是否是相同的字节。您还应该检查每个填充字节是不是零还是大于块大小。