【发布时间】:2018-01-13 08:26:44
【问题描述】:
我一直在尝试复制一个使用 md5 作为密钥进行 AES256 加密的 android 代码。一切似乎都很好,但加密后的值似乎不一样。请通过我的以下代码
安卓:-
public static String encrypt(String key, String value) {
try {
byte[] keyArr = new byte[32];
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] hash = md.digest(key.getBytes("US-ASCII"));//in md5 function 1st line
keyArr = arrayCopy(0, hash, 0, keyArr, 16);//in md5 function 1st for loop
keyArr = arrayCopy(0, hash, 15, keyArr, 16);//in md5 function 2nd for loop
SecretKeySpec skeySpec = new SecretKeySpec(keyArr, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
byte[] encrypted = cipher.doFinal(value.getBytes());
String encryptedB64 = new String(Base64.encode(encrypted, Base64.DEFAULT));
return encryptedB64;
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
private static byte[] arrayCopy(int sourceIndex,byte[] source,int targetIndex,byte[] target,int transferSize){
if(!(transferSize >0))
return null;
if(sourceIndex>=0 && sourceIndex < source.length){
int transferCnt=0;
int i=sourceIndex;
for(int j=targetIndex;;j++,i++){
if(targetIndex>=target.length || sourceIndex>=source.length || (++transferCnt>transferSize)){
break;
}
target[j] = source[i];
}
}else{
return null;
}
return target;
}
iOS 目标-c
+ (NSString *) getFalconEncryptedValueForKey:(NSString *)theKey forString:(NSString *)theString
{
char keyPtr[kCCKeySizeAES256+1]; // room for terminator (unused)
bzero(keyPtr, sizeof(keyPtr)); // fill with zeroes (for padding)
NSData *rawData = [theString dataUsingEncoding:NSUTF8StringEncoding];
NSString *md5Key = [self md5:theKey];
[md5Key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
NSUInteger dataLength = [rawData length];
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void *buffer = malloc(bufferSize);
size_t numBytesEncrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding + kCCOptionECBMode,
keyPtr, kCCKeySizeAES256,
NULL /* initialization vector (optional) */,
[rawData bytes], dataLength, /* input */
buffer, bufferSize, /* output */
&numBytesEncrypted);
if (cryptStatus == kCCSuccess)
{
NSData *tempData = [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
NSString* encrypted64 = [tempData base64EncodedStringWithOptions:0];//Even i have tried base 64 encding with other options available
return encrypted64;
}
free(buffer); //free the buffer;
return nil;
}
+ (NSString *) md5:(NSString *) input
{
// const char * pointer = [self UTF8String];
const char *cStr = [input cStringUsingEncoding:NSASCIIStringEncoding];
unsigned char result[CC_MD5_DIGEST_LENGTH];
CC_MD5( cStr, (CC_LONG)strlen(cStr), result );
NSMutableString *md5String = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2];
for (int i = 0; i < CC_MD5_DIGEST_LENGTH; i++)
[md5String appendFormat:@"%02x",result[i]];
for (int i = 0; i < CC_MD5_DIGEST_LENGTH; i++)
[md5String appendFormat:@"%02x",result[i]];
return md5String;
//for 32 byte. md5 produces only 16 byte info. we are replicating it again to make it 32 byte for aes256
}
任何对我做错的方向的指导都会非常有帮助。提前致谢
【问题讨论】:
-
如果没有实现
arrayCopy,这纯属猜测。 -
此代码有几个问题: 1. 可能使用 128 位密钥并将其扩展到 256 位,没有任何额外的安全性。 2.如果
key实际上是一个密码,那么简单的散列是不够的。使用 PBKDF2 或类似的。 3.Cipher.getInstance("AES");可能使用ECB模式,这与insecure相当。 4. 密文没有认证,所以攻击者可能会在你没有察觉的情况下修改密文。使用 GCM 等认证模式或将 HMAC 应用于密文。 -
不,那是另一回事。
-
其实java-samples.com/showtutorial.php?tutorialid=641也就是已经使用的函数了。它也是由第三方供应商编写的代码,我对此没有发言权。不,密钥不是密码。它是一个加密的字符串。你能帮我找出我在转换代码时遗漏的地方吗?
标签: android ios objective-c aes md5