大佬教程收集整理的这篇文章主要介绍了java – AES加密Android < - > iOS不同的结果,消息长度> 15字节,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
我在理解两个设备上的密码/加密器时遇到了一个真正的问题.
1.
如果我们使用Cipher AES加密iOS和Android上的消息并且字符串的charlength不大于16(例如“abcdefghijklmno”),我们在使用相同的密钥/密码加密后得到相同的结果.
2.
但是如果需要更长的消息,我们会在iOS和Android上获得不同的结果(例如“abcdefghijklmnop”)
我做了很多研究如何为这两种设备获得相同的参数,起初我认为它是安全的.
这是我用于加密的密码:
public String encode(Context context, String password, String text)
throws NoPassGivenException, NoTextGivenException {
if (password.length() == 0 || password == null) {
throw new NoPassGivenException("Please give password");
}
if (text.length() == 0 || text == null) {
throw new NoTextGivenException("Please give text");
}
try {
SecretKeySpec skeySpec = getKey(password);
byte[] clearText = text.getBytes("UTF8");
//IMPORTANT TO GET SAME RESULTS ON iOS and ANDROID
final byte[] iv = new byte[16];
Arrays.fill(iv, (bytE) 0x00);
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
// Cipher is not thread safe
//EDITED AFTER RIGHT ANSWER FROM
//*** Cipher cipher = Cipher.geTinstance("AES"); ***//
// TO
Cipher cipher = Cipher.geTinstance("AES/CBC/PKCS7Padding");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, ivParameterSpec);
String encrypedValue = Base64.encodeToString(
cipher.doFinal(clearText), Base64.DEFAULT);
Log.d(tag, "Encrypted: " + text + " -> " + encrypedvalue);
return encrypedValue;
} catch (InvalidKeyException E) {
e.printStackTrace();
} catch (UnsupportedEncodingException E) {
e.printStackTrace();
} catch (NoSuchAlgorithmException E) {
e.printStackTrace();
} catch (BadPaddingException E) {
e.printStackTrace();
} catch (NoSuchPaddingException E) {
e.printStackTrace();
} catch (IllegalBlockSizeException E) {
e.printStackTrace();
} catch (InvalidAlgorithmParameterException E) {
e.printStackTrace();
}
return "";
}
public SecretKeySpec getKey(String password)
throws UnsupportedEncodingException {
int keyLength = 128;
byte[] keyBytes = new byte[keyLength / 8];
// explicitly fill with zeros
Arrays.fill(keyBytes, (bytE) 0x0);
// if password is shorter then key length, it will be zero-padded
// to key length
byte[] passwordBytes = password.getBytes("UTF-8");
int length = passwordBytes.length < keyBytes.length ? passwordBytes.length
: keyBytes.length;
System.arraycopy(passwordBytes, 0, keyBytes, 0, length);
SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");
return key;
}
这是我的同事的iOS挂件:
- (NSData *)AES128EncryptWithKey:(NSString *)key {
// 'key' should be 32 bytes for AES256,
// 16 bytes for AES256, will be null-padded otherwise
char keyPtr[kCCKeySizeAES128 + 1]; // room for terminator (unused)
bzero(keyPtr, sizeof(keyPtr)); // fill with zeroes (for padding)
// insert key in char array
[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;
// the encryption method, use always same attributes in android and iPhone (f.e. PKCS7Padding)
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,
kCCAlgorithmAES128,
kCCOptionPKCS7Padding,
keyPtr,
kCCKeySizeAES128,
NULL /* initialization vector (optional) */,
[self bytes], dataLength, /* input */
buffer, bufferSize, /* output */
&numbytesEncrypted);
if (cryptStatus == kCCsuccess) {
return [NSData dataWithBytesnoCopy:buffer length:numbytesEncrypted];
}
free(buffer);
return nil;
}
我真的很想了解差异是什么以及如何避免它.与更大的字符串超过15个字符的测试给了我一个提示,但我不知道为什么:)
先谢谢你们!
解决方法:
检查两个系统上正在使用的填充.不同的填充将导致不同的输出.不要依赖默认值,而是明确设置两侧的填充.您的第二个代码片段显式设置PKCS7填充.在两端使用它.
作为一般规则,不要依赖于不同系统之间的默认值.明确设置IV,模式,填充,随机数或其他任何需要的东西.即使最微小的细节不匹配,加密也会失败.
以上是大佬教程为你收集整理的java – AES加密Android < - > iOS不同的结果,消息长度> 15字节全部内容,希望文章能够帮你解决java – AES加密Android < - > iOS不同的结果,消息长度> 15字节所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。