參考來源:https://stackoverflow.com/questions/7152995/pbewithmd5anddes-encryption-in-ios
聲明:這是我工(趕)作(鴨)需(子)要(上架),在接觸oc不到半個月情況下完成的,有任何錯誤敬請諒解并歡迎指出
正文
廢話不多說,直接上代碼
#include <CommonCrypto/CommonDigest.h>
#include <CommonCrypto/CommonCryptor.h>
+(NSData*) cryptPBEWithMD5AndDES:(CCOperation)op usingData:(NSData*)data withPassword:(NSString*)password andSalt:(NSData*)salt andIterating:(int)numIterations {
unsigned char md5[CC_MD5_DIGEST_LENGTH];
memset(md5, 0, CC_MD5_DIGEST_LENGTH);
NSData* passwordData = [password dataUsingEncoding:NSUTF8StringEncoding];
CC_MD5_CTX ctx;
CC_MD5_Init(&ctx);
CC_MD5_Update(&ctx, [passwordData bytes], [passwordData length]);
CC_MD5_Update(&ctx, [salt bytes], [salt length]);
CC_MD5_Final(md5, &ctx);
for (int i=1; i<numIterations; i++) {
CC_MD5(md5, CC_MD5_DIGEST_LENGTH, md5);
}
size_t cryptoResultDataBufferSize = [data length] + kCCBlockSizeDES;
unsigned char cryptoResultDataBuffer[cryptoResultDataBufferSize];
size_t dataMoved = 0;
unsigned char iv[kCCBlockSizeDES];
memcpy(iv, md5 + (CC_MD5_DIGEST_LENGTH/2), sizeof(iv)); //iv is the second half of the MD5 from building the key
CCCryptorStatus status =
CCCrypt(op, kCCAlgorithmDES, kCCOptionPKCS7Padding, md5, (CC_MD5_DIGEST_LENGTH/2), iv, [data bytes], [data length],
cryptoResultDataBuffer, cryptoResultDataBufferSize, &dataMoved);
if(0 == status) {
return [NSData dataWithBytes:cryptoResultDataBuffer length:dataMoved];
} else {
return NULL;
}
}
直接stackoverflow上扒下來的代碼。
Java部分代碼可以參考 JAVA加解密14-對稱加密算法-PBE算法 (來自 K1024)
簡單測試
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSString *dataStr = @"hello, world";
NSData *data = [dataStr dataUsingEncoding:NSUTF8StringEncoding];
NSData *salt = [@"salt" dataUsingEncoding:NSUTF8StringEncoding];
// 加密
NSData *encryptData = [test cryptPBEWithMD5AndDES:(kCCEncrypt) usingData:data withPassword:@"passwd" andSalt:salt andIterating:20];
NSLog(@"%@", encryptData);
//解密
NSData *decryptData=[test cryptPBEWithMD5AndDES:(kCCDecrypt) usingData:encryptData withPassword:@"passwd" andSalt:salt andIterating:20];
NSLog(@"%@", decryptData);
NSLog(@"text:%@",[[NSString alloc] initWithData:decryptData encoding:NSUTF8StringEncoding]);
}
return 0;
}
輸出
2019-02-27 20:49:43.566299+0800 OcDemo[5046:282195] <99ffe825 57031ab9 980bfb8e 33baefc1>
2019-02-27 20:49:43.566527+0800 OcDemo[5046:282195] <68656c6c 6f2c2077 6f726c64>
2019-02-27 20:49:43.566580+0800 OcDemo[5046:282195] text:hello, world
Program ended with exit code: 0
幾點注意
- 參數(shù)中 numIterations 為迭代次數(shù),加密解密需要一致。
- 和Java中有一點不太一樣的就是oc中NSData顯示的是16進(jìn)制的數(shù),而在Java中byte顯示的為有符號數(shù),所以會出現(xiàn)負(fù)數(shù)的情況。因此不是不一樣,只是展示問題,實際Java中對應(yīng)16進(jìn)制無符號的展示應(yīng)該和oc的結(jié)果相同,可以自己做一下轉(zhuǎn)換對比(注意補(bǔ)碼轉(zhuǎn)換十進(jìn)制的規(guī)則)。
- 網(wǎng)上有一些會說salt不能取到大于128,理由就是我上面說的,實際是沒有影響的。因為雖然展示出來的數(shù)據(jù)不一樣(Java為負(fù)數(shù),oc為正數(shù)),但其底層的二進(jìn)制表達(dá)是一致的,所以不影響最終加解密。