Triển khai AES256 trên iOS bằng chức năng CCCrypt. Nhưng đầu ra và chiều dài bộ đệm đầu ra khác với Android.Mã hóa AES trên iOS và android, đầu ra và kích thước bộ đệm khác nhau
Lớp mật mã trong Android tạo dữ liệu 48 byte trong đó trong iOS, chúng tôi nhận được dữ liệu 80 byte.
Trong IOS sử dụng kCCAlgorithmAES, kCCOptionPKCS7Padding và trong android bằng AES/CBC/PKCS5Padding.
trong IOS IV là NULL và tạo android iv làm mảng 16 byte mới.
Vui lòng trợ giúp.
vui lòng tìm đầu vào và mã để tham khảo.
- (void)viewDidLoad {
[super viewDidLoad];
NSString *message = [NSString stringWithFormat:@"com.myapp.com|355004059196637|911111111111|11341e5e-9643-4559-bbb7-34d40555e96c"];
NSString *key = [NSString stringWithFormat:@"4f28d5901b4b7b80d33fda76ca372c2a20bd1a6c2aad7fa215dc79d507330678"];
NSString *shaEncryptMessage = [self sha256:message length:0];
NSData *aesEncryptData = [self aesEncrypt:[shaEncryptMessage dataUsingEncoding:NSUTF8StringEncoding] key:key iv:nil];
NSString *hMac = [aesEncryptData base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
NSLog(@"hMac = %@",hMac);
// IOS output : Can+oQR79D3/lsQGctzY/d2VBNZbWWtJxGI8iRIu80R2yTskn9gf2oKHaRESX73u
// LpJHLx1Xr6iH11jFPlmqwW7mQz0xAW4uACNAMEoZ0kY=
// Android output : MiMDkdo5cGsPMj2qCnNobgp7dr5KMvBhGuKTonrqr1lCYte/kKegGMtI/4TPhUNI
}
- (NSString*) sha256:(NSString *)key length:(NSInteger) length{
const char *s=[key cStringUsingEncoding:NSASCIIStringEncoding];
NSData *keyData=[NSData dataWithBytes:s length:strlen(s)];
uint8_t digest[CC_SHA256_DIGEST_LENGTH]={0};
CC_SHA256(keyData.bytes, (unsigned int)keyData.length, digest);
NSData *out=[NSData dataWithBytes:digest length:CC_SHA256_DIGEST_LENGTH];
NSString *hash=[out description];
hash = [hash stringByReplacingOccurrencesOfString:@" " withString:@""];
hash = [hash stringByReplacingOccurrencesOfString:@"<" withString:@""];
hash = [hash stringByReplacingOccurrencesOfString:@">" withString:@""];
return hash;
}
- (NSData *)aesEncrypt:(NSData *)plainText key:(NSString *)key iv:(NSString *)iv {
char keyPointer[kCCKeySizeAES256+2],// room for terminator (unused) ref: https://devforums.apple.com/message/876053#876053
ivPointer[kCCBlockSizeAES128];
BOOL patchNeeded;
bzero(keyPointer, sizeof(keyPointer)); // fill with zeroes for padding
//key = [[StringEncryption alloc] md5:key];
key = [self stringFromHex:key];
patchNeeded= ([key length] > kCCKeySizeAES256+1);
if(patchNeeded)
{
key = [key substringToIndex:kCCKeySizeAES256]; // Ensure that the key isn't longer than what's needed (kCCKeySizeAES256)
}
[key getCString:keyPointer maxLength:sizeof(keyPointer) encoding:NSUTF8StringEncoding];
[iv getCString:ivPointer maxLength:sizeof(ivPointer) encoding:NSUTF8StringEncoding];
// if (patchNeeded) {
// keyPointer[0] = '\0'; // Previous iOS version than iOS7 set the first char to '\0' if the key was longer than kCCKeySizeAES256
// }
NSUInteger dataLength = [plainText length];
// For block ciphers, the output size will always be less than or equal to the input size plus the size of one block.
size_t buffSize = dataLength + kCCBlockSizeAES128;
void *buff = malloc(buffSize);
size_t numBytesEncrypted = 0;
CCCryptorStatus status = CCCrypt(kCCEncrypt, /* kCCEncrypt, etc. */
kCCAlgorithmAES128, /* kCCAlgorithmAES128, etc. */
kCCOptionPKCS7Padding, /* kCCOptionPKCS7Padding, etc. */
keyPointer, kCCKeySizeAES256, /* key and its length */
NULL, /* initialization vector - use random IV everytime */
[plainText bytes], [plainText length], /* input */
buff, buffSize,/* data RETURNED here */
&numBytesEncrypted);
if (status == kCCSuccess) {
return [NSData dataWithBytesNoCopy:buff length:numBytesEncrypted];
}
free(buff);
return nil;
}
- (NSString *) stringFromHex:(NSString *)str
{
NSMutableData *stringData = [[NSMutableData alloc] init];
unsigned char whole_byte;
char byte_chars[3] = {'\0','\0','\0'};
int i;
for (i=0; i < [str length]/2; i++) {
byte_chars[0] = [str characterAtIndex:i*2];
byte_chars[1] = [str characterAtIndex:i*2+1];
whole_byte = strtol(byte_chars, NULL, 16);
[stringData appendBytes:&whole_byte length:1];
}
return [[NSString alloc] initWithData:stringData encoding:NSASCIIStringEncoding];
}
Hãy tìm mã android cũng có,
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
generateHMAC();
}
String K0 = "4f28d5901b4b7b80d33fda76ca372c2a20bd1a6c2aad7fa215dc79d507330678";
String generatedString = "com.myapp.com|355004059196637|911111111111|11341e5e-9643-4559-bbb7-34d40555e96c";
private void generateHMAC() {
Log.d("Message of Hash", generatedString);
byte[] var14 = new byte[0];
try {
var14 = SHA256(generatedString);
byte[] var15 = new byte[0];
var15 = encrypt(var14, hexStringToByteArray(K0));
String var4 = Base64.encodeToString(var15, 2);
Log.d("Existing K0", K0);
Log.d("HMAC", var4);
} catch (Exception e) {
e.printStackTrace();
}
}
public byte[] SHA256(String paramString) throws Exception {
MessageDigest md = MessageDigest.getInstance("SHA-256");
md.update(paramString.getBytes("UTF-8"));
byte[] digest = md.digest();
return digest;
}
public byte[] encrypt(byte[] var1, byte[] var2) throws Exception {
SecretKeySpec var3 = new SecretKeySpec(var2, "AES");
byte[] var4 = new byte[16];
IvParameterSpec var5 = new IvParameterSpec(var4);
Cipher var6 = Cipher.getInstance("AES/CBC/PKCS5Padding");
var6.init(1, var3, var5);
byte[] var7 = var6.doFinal(var1);
return var7;
}
public byte[] hexStringToByteArray(String var1) {
byte[] var2 = new byte[var1.length()/2];
for (int var3 = 0; var3 < var2.length; ++var3) {
int var4 = var3 * 2;
int var5 = Integer.parseInt(var1.substring(var4, var4 + 2), 16);
var2[var3] = (byte) var5;
}
return var2;
}
hãy thử https://github.com/alexeypro/EncryptDecrypt AES256EncryptWithKey – Rivendell
Bạn có thể đăng mã không? – TheGreatContini
Mặc dù điều này không trả lời câu hỏi của bạn, bạn nên biết rằng mặc dù Apple cho bạn biết rằng Vector khởi tạo (IV) là tùy chọn, mã hóa không an toàn nếu bạn không chỉ định và chọn IV theo cách không thể đoán trước. Xấu hổ về Apple cho API mã hóa kém này. – TheGreatContini