用AES 128,ecb模式在openssl上加密并在iPhone上解密

更新:找到解决方案。 我将很快用实际的工作代码和命令更新这个问题。


客户端正在用C ++加密文件服务器端,我需要在iPhone应用程序中解密它。

我的客户可以在他的身边进行加密和解密,我也可以在iPhone上进行解密,但我们无法解密彼此加密的文件。 我看到很多关于SO的相关问题,但没有人能帮助我找到一个在两边都以相同方式工作的实现。

我想输出一些我们将接受的样本值作为通用实现。

我尝试用openssl加密一个文件并用可可解密,但是不能。

以下是我用于加密的内容:

echo "123456789ABCDEFG" | openssl enc -aes-128-ecb -nosalt -K "41414141414141414141414141414141" -iv 0 > hello.txt.bin

将选项-p添加到openssl调用显示使用期望的密钥和iv:

key=41414141414141414141414141414141
iv =00000000000000000000000000000000

对于可可解密(在NSData类别中):

- (NSData *)AESDecryptWithKey:(NSString *)key {

    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:NSUTF8StringEncoding];

    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 numBytesEncrypted = 0;

    char iv[32];
    for (int i = 0; i < 32; i++) {
        iv[i] = 0;
    }

    CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128, kCCOptionECBMode + kCCOptionPKCS7Padding,
                                          keyPtr, kCCKeySizeAES128,
                                          iv, //"00000000000000000000000000000000" /* initialization vector (optional) */,
                                          [self bytes], dataLength, /* input */
                                          buffer, bufferSize, /* output */
                                          &numBytesEncrypted);

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

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

这样称呼:

- (void)testBinaryFileDecryption {
    NSString *databasePath = [[NSBundle mainBundle] pathForResource:@"hello" ofType:@"txt.bin"];

    NSData *data = [NSData dataWithContentsOfFile:databasePath];
    NSAssert(nil != data, @"Encrypted data, freshly loaded from file should not be nil");

    NSData *plain = [data AESDecryptWithKey:@"AAAAAAAAAAAAAAAA"];
    NSAssert(nil != plain, @"Decrypted plain data should not be nil");

    NSLog(@"Result: '%@'", [[NSString alloc] initWithData:plain encoding:NSASCIIStringEncoding]);
}

结果日志: Result: '4¨µ¢Ä½Pk£N

我忘了什么选项? NSData的编码是否返回了NSASCIIStringEncoding以外的内容?


我对iPhone开发一无所知,但看着这段代码,似乎你正在尝试使用实际密钥的十六进制编码来解密数据包。 OpenSSL的enc需要十六进制编码,因为它将十六进制转换为字节。 直接转换为ascii时,您的实际密钥看起来更像这样。

["37", " ", "!", """, "#", "$", "%", "&", "'", "36", "37", " ", "!", """, "#", "$"]

(所有这些可能都是钝的,如果你要将你用来解密的字符串编码成OpenSSL 3331333233333334333533363337333833393330333133323333333433353336接受的相同格式,密钥将是3331333233333334333533363337333833393330333133323333333433353336

尝试在您的iPhone代码中使用41414141414141414141414141414141的关键规范来使用OpenSSL并使用AAAAAAAAAAAAAAAA

另外,我强烈建议您使用长度恰好为N * 16个字节的数据进行初始测试。 OpenSSL enc使用PKCS#5填充(除非使用-nopad ),并且您的iPhone代码使用PKCS#7填充。 粗略看一下RFC,它们似乎是相同的填充机制,但我可能是错的。

而且我知道你只是在这里尝试一些东西,但在实际生产代码中,请不要使用ECB模式。


我使用Crypt :: OpenSSL :: AES来加密在我的iOS应用程序中解密的文件,该应用程序使用CommonCryptor进行解密。

    cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128, 0,
                          keyPtr, kCCKeySizeAES256,
                          IVECTOR /* initialization vector (optional) -- was NULL*/,
                          [self bytes], dataLength, /* input */
                          buffer, bufferSize, /* output */
                          &numBytesDecrypted);

要初始化IVECTOR,我正在使用bzero。

bzero(keyPtr, sizeof(keyPtr)); // fill with zeroes (for padding)

在perl下加密OpenSSL我这样做:

my $cipher = Crypt::CBC->new( -key    => $key,
                              -literal_key => 1,
                              -header => 'none',
                              -iv =>     '0000000000000000',
                              -cipher => 'Crypt::OpenSSL::AES' );

OpenSSL似乎接受'0000000000000000'IV作为与ASCII 0(空)字符相同的东西。 似乎回想起来似乎合理,但它需要大量的头发拉,因为每个加密失败看起来像其他加密失败:垃圾出。

链接地址: http://www.djcxy.com/p/27741.html

上一篇: Encrypt with openssl and decrypt on iPhone with AES 128, ecb mode

下一篇: password encryption in iphone apps