加密与openssl和解密在iPhone与AES 128,ecb模式 [英] Encrypt with openssl and decrypt on iPhone with AES 128, ecb mode

查看:176
本文介绍了加密与openssl和解密在iPhone与AES 128,ecb模式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

更新:找到了解决方案。我会尽快用实际的工作代码和命令更新此问题。






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



我的客户端可以在他身边加密和解密,所以我在iPhone上,但我们可以' t对彼此加密的文件进行解密。
我看到许多相关的问题,但没有一个可以帮助我找到一个实现,以相同的方式在两边。



我想输出一些样本



我试图用openssl隐藏一个文件并用可可解密,但不能。



这里是我用于加密:



echo123456789ABCDEFG| openssl enc-aes-128-ecb-nosalt -K41414141414141414141414141414141-iv 0> hello.txt.bin



向openssl调用添加选项-p显示使用预期的键和iv:

  key = 414141414141414141414141414141414 
iv = 00000000000000000000000000000000

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

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

char keyPtr [kCCKeySizeAES128 + 1]; //用于终止符的空间(未使用)
bzero(keyPtr,sizeof(keyPtr)); //填充零(用于填充)

//获取关键数据
[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;

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

CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt,kCCAlgorithmAES128,kCCOptionECBMode + kCCOptionPKCS7Padding,
keyPtr,kCCKeySizeAES128,
iv,//00000000000000000000000000000000/ *初始化向量可选)* /,
[self bytes],dataLength,/ * input * /
buffer,bufferSize,/ * output * /
& numBytesEncrypted);

if(cryptStatus == kCCSuccess){
//返回的NSData获取缓冲区的所有权并在释放时释放它
return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted] ;
}

free(buffer); //释放缓冲区
return nil;
}

这样调用:

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

NSData * data = [NSData dataWithContentsOfFile:databasePath];
NSAssert(nil!= data,@加密数据,从文件新装入的数据不应为nil);

NSData * plain = [data AESDecryptWithKey:@AAAAAAAAAAAAAAAA'];
NSAssert(nil!= plain,@解密的明文数据不应该是nil);

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

结果日志:
结果:'4¨μ¢ ĽPk£N



我忘记了什么选择? NSData的编码是否返回了NSASCIIStringEncoding?

解决方案

我对iPhone开发没有什么感觉,它似乎你正在尝试使用十六进制编码的实际密钥来解密数据包。 OpenSSL的enc需要十六进制编码,因为它将hex转换为字节。


 <$ c $ 

c[\ 037,,!,\,#,$,%,& \ 037,,!,\,#,$]


< blockquote>

(所有这些可能是钝的。如果你要使用OpenSSL enc接受的同一格式编码你正在使用的字符串,密钥将是 3331333233333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333433353336 。)



尝试使用 41414141414141414141414141414141414141414141414141 的键规范来OpenSSL请在您的iPhone代码中使用 AAAAAAAAAAAAAAAA



此外,我强烈建议您使用N * 16字节长。 OpenSSL enc使用PKCS#5填充(除非使用 -nopad ),并且您的iPhone代码使用PKCS#7填充。粗略地看一下RFC,他们似乎是相同的填充机制,但我可能是错误的。



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

Update : found the solution. I will update this question soon with the actual working code and command.


A client is encrypting a file server-side with C++, and I need to decrypt it in an iPhone application.

My client can crypt and decrypt on his side, and so do I on the iPhone, but we can't decrypt the file encrypted by each other. I saw many related questions on SO, but none could help me find an implementation that works the same way on both side.

I want to output some sample values that we will accept as the common implementation.

I tried to crypt a file with openssl and decrypt it with cocoa, but couldn't.

Here is what I use for encryption:

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

Adding the option -p to openssl call shows that the expected key and iv are used:

key=41414141414141414141414141414141
iv =00000000000000000000000000000000

And for cocoa decryption (in an NSData category):

- (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;
}

called this way:

- (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 logs: Result: '4¨µ¢Ä½Pk£N

What option am I forgetting? Is the encoding of the NSData returned something else than NSASCIIStringEncoding ?

解决方案

I know nothing of iPhone development, but looking at this code, it appears you're trying to use the ascii-of-hex-encoding of the actual key to decrypt the packet. OpenSSL's enc requires the hex encoding because it converts the hex into bytes. Your actual key looks more like this, when converted directly to ascii.

["\037", " ", "!", "\"", "#", "$", "%", "&", "'", "\036", "\037", " ", "!", "\"", "#", "$"]

(All that might be obtuse. If you were to encode the string you're using for decrypting into the same format that OpenSSL enc accepts, the key would be 3331333233333334333533363337333833393330333133323333333433353336.)

Try using a key specification of 41414141414141414141414141414141 to OpenSSL and use AAAAAAAAAAAAAAAA in your iPhone code.

Also, I strongly suggest your initial tests be made with data that is exactly N*16 bytes long. OpenSSL enc uses PKCS#5 padding (unless you use -nopad), and your iPhone code is using PKCS#7 padding. On a cursory glance at RFCs, they seem to be the same padding mechanism, but I could be wrong.

And I know you're just trying things out here, but in real production code, please do not use ECB mode.

这篇关于加密与openssl和解密在iPhone与AES 128,ecb模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆