使用PKCS7Padding进行AES CBC加密在Java和Objective-C中具有不同的结果 [英] AES CBC Encryption With PKCS7Padding Has Different Results In Java And Objective-C
问题描述
我用Java创建了一个Android应用程序,并使用 Cipher
类用AES加密数据.现在,我想通过 CommonCrypto
类将该算法带入iOS.该代码有效,但结果不同.
I have created an application for Android in Java and used Cipher
class to encrypt data with AES. Now I wanna take that algorithm into iOS with CommonCrypto
class. The code works but has different results.
这是 Java 中的代码:
public static String Decrypt(String text, String key) throws Exception {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
byte[] keyBytes = new byte[16];
byte[] b = key.getBytes("UTF-8");
int len = b.length;
if (len > keyBytes.length)
len = keyBytes.length;
System.arraycopy(b, 0, keyBytes, 0, len);
SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");
IvParameterSpec ivSpec = new IvParameterSpec(keyBytes);
cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
byte[] results = new byte[text.length()];
BASE64Decoder decoder = new BASE64Decoder();
try {
results = cipher.doFinal(decoder.decodeBuffer(text));
} catch (Exception e) {
System.out.print("Erron in Decryption");
}
return new String(results, "UTF-8");
}
public static String Encrypt(String text, String key) throws Exception {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
byte[] keyBytes = new byte[16];
byte[] b = key.getBytes("UTF-8");
int len = b.length;
if (len > keyBytes.length)
len = keyBytes.length;
System.arraycopy(b, 0, keyBytes, 0, len);
SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");
IvParameterSpec ivSpec = new IvParameterSpec(keyBytes);
System.out.println(keyBytes);
System.out.println(keySpec);
System.out.println(ivSpec);
cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
byte[] results = cipher.doFinal(text.getBytes("UTF-8"));
BASE64Encoder encoder = new BASE64Encoder();
return encoder.encode(results);
}
这是 Objective-C 中的代码:
+ (NSString*)AES256EncryptData:(NSString*)data WithKey:(NSString*)key {
char keyPtr[kCCKeySizeAES128]; // 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 = data.length;
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void* buffer = malloc(bufferSize);
size_t numBytesEncrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding,
keyPtr, kCCKeySizeAES256,
NULL /* initialization vector (optional) */,
data.UTF8String, dataLength, /* input */
buffer, bufferSize, /* output */
&numBytesEncrypted);
if (cryptStatus == kCCSuccess) {
return [[NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted] base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithCarriageReturn];
}
free(buffer); //free the buffer;
return nil;
}
+ (NSString*)AES256DecryptData:(NSString*)data WithKey:(NSString*)key {
char keyPtr[kCCKeySizeAES256 + 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 = data.length;
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void* buffer = malloc(bufferSize);
size_t numBytesDecrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding,
keyPtr, kCCKeySizeAES256,
NULL /* initialization vector (optional) */,
data.UTF8String, dataLength, /* input */
buffer, bufferSize, /* output */
&numBytesDecrypted);
if (cryptStatus == kCCSuccess) {
return [[NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted] base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithCarriageReturn];
}
free(buffer); //free the buffer;
return nil;
}
更新1:
数据:要加密的文本
键: testkey
Java (所需)结果: 7ptTEyImNz9KgC96 + JPFXQ ==
Objective-C结果: U7FAVHi01q0Hhf + m9NsKjw ==
Objective-C Result: U7FAVHi01q0Hhf+m9NsKjw==
推荐答案
您的问题出在Objective-C代码上.您应该在Java和Obj-C中使用相同的方法.您可以使用以下代码来使其返回相同的结果:
Your problem is with the Objective-C code. You should use same method in both Java and Obj-C. You can use this code in order to make it return the same results:
AES.h
#import <Foundation/Foundation.h>
#import <CommonCrypto/CommonCrypto.h>
@interface AES : NSObject
+ (NSData *)Encrypt:(NSString *)data WithKey:(NSString *)key;
+ (NSString *)Decrypt:(NSData *)data WithKey:(NSString *)key;
+ (NSData *)AESOperation:(CCOperation)operation OnData:(NSData *)data key:(NSString *)key;
@end
AES.m
#import "AES.h"
@implementation AES
+ (NSData *)Encrypt:(NSString *)data WithKey:(NSString *)key {
return [self AESOperation:kCCEncrypt OnData:[data dataUsingEncoding:NSUTF8StringEncoding] key:key];
}
+ (NSString *)Decrypt:(NSData *)data WithKey:(NSString *)key {
return [[NSString alloc] initWithData:[self AESOperation:kCCDecrypt OnData:data key:key] encoding:NSUTF8StringEncoding];
}
+ (NSData *)AESOperation:(CCOperation)operation OnData:(NSData *)data key:(NSString *)key {
char keyPtr[kCCKeySizeAES128];
bzero(keyPtr, sizeof(keyPtr));
[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
NSUInteger dataLength = [data length];
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void *buffer = malloc(bufferSize);
size_t numBytesEncrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(operation,
kCCAlgorithmAES128,
kCCOptionPKCS7Padding,
keyPtr,
kCCBlockSizeAES128,
keyPtr,
[data bytes],
dataLength,
buffer,
bufferSize,
&numBytesEncrypted);
if (cryptStatus == kCCSuccess) {
return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
}
free(buffer);
return nil;
}
@end
这篇关于使用PKCS7Padding进行AES CBC加密在Java和Objective-C中具有不同的结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!