用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