美文网首页
iOS Objective-C PBEWithMD5AndDES

iOS Objective-C PBEWithMD5AndDES

作者: TreviD | 来源:发表于2019-02-27 20:59 被阅读0次

参考来源: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

几点注意

  • 参数中 numIterations 为迭代次数,加密解密需要一致。
  • 和Java中有一点不太一样的就是oc中NSData显示的是16进制的数,而在Java中byte显示的为有符号数,所以会出现负数的情况。因此不是不一样,只是展示问题,实际Java中对应16进制无符号的展示应该和oc的结果相同,可以自己做一下转换对比(注意补码转换十进制的规则)。
  • 网上有一些会说salt不能取到大于128,理由就是我上面说的,实际是没有影响的。因为虽然展示出来的数据不一样(Java为负数,oc为正数),但其底层的二进制表达是一致的,所以不影响最终加解密。

相关文章

网友评论

      本文标题:iOS Objective-C PBEWithMD5AndDES

      本文链接:https://www.haomeiwen.com/subject/dplquqtx.html