iOS 中 3DES加密、MD5加密

加密算法通常分为对称性加密算法和非对称性加密算法,以及线性散列算法,对应着比较常见的是 DES,RSA,MD5。

  • 对称性加密算法,信息接收双方都需事先知道密匙和加解密算法且其密匙是相同的,之后便是对数据进行加解密了。
  • 非对称加密算法,发送双方A,B事先均生成一堆密匙,然后A将自己的公有密匙发送给B,B将自己的公有密匙发送给A,如果A要给B发送消 息,则先需要用B的公有密匙进行消息加密,然后发送给B端,此时B端再用自己的私有密匙进行消息解密,B向A发送消息时为同样的道理。
  • 线性散列加密算法, 只生成一串不可逆的密文,经常用其效验数据传输过程中是否经过修改,因为相同的生成算法对于同一明文只会生成唯一的密文,若相同算法生成的密文不同,则证明传输数据进行过了修改。

3DES 和 MD5 是我用到过的,特此记录下。

3DES

3DES是一种基于DES的加密算法,使用3个不同密匙对同一个分组数据块进行3次加密,如此以使得密文强度更高。

当然一般我们现有的涉及到文件/信息加密,或提高数据安全级别一般都会选择 CommonCrypto 来完成任务。

可以从Oc 上面先了解它的函数声明:

CCCryptorStatus CCCrypt(
       CCOperation op,          // operation: kCCEncrypt or kCCDecrypt
       CCAlgorithm alg,         // algorithm: kCCAlgorithmAES128... 
       CCOptions options,       // operation: kCCOptionPKCS7Padding...
       const void *key,         // key
       size_t keyLength,        // key length
       const void *iv,          // initialization vector (optional)
       const void *dataIn,      // input data
       size_t dataInLength,     // input data length
       void *dataOut,           // output data buffer
       size_t dataOutAvailable, // output data length available
       size_t *dataOutMoved)    // real output data length generated
  )

Swift + 3DES

extension String {
 
    /**
    3DES的加密过程 和 解密过程
    
    - parameter op : CCOperation: 加密还是解密
                     CCOperation(kCCEncrypt)加密
                     CCOperation(kCCDecrypt) 解密
     
    - parameter key: 专有的key,一个钥匙一般
    - parameter iv : 可选的初始化向量,可以为nil
    - returns      : 返回加密或解密的参数
    */
    func threeDESEncryptOrDecrypt(op: CCOperation,key: String,iv: String) -> String? {
        
        // Key
        let keyData: NSData = (key as NSString).dataUsingEncoding(NSUTF8StringEncoding) as NSData!
        let keyBytes         = UnsafeMutablePointer(keyData.bytes)
        
        // 加密或解密的内容
        var data: NSData = NSData()
        if op == CCOperation(kCCEncrypt) {
            data  = (self as NSString).dataUsingEncoding(NSUTF8StringEncoding) as NSData!
        }
        else {
            data =  NSData(base64EncodedString: self, options: NSDataBase64DecodingOptions.IgnoreUnknownCharacters)!
        }
        
        let dataLength    = size_t(data.length)
        let dataBytes     = UnsafeMutablePointer(data.bytes)
        
        // 返回数据
        let cryptData    = NSMutableData(length: Int(dataLength) + kCCBlockSize3DES)
        let cryptPointer = UnsafeMutablePointer(cryptData!.mutableBytes)
        let cryptLength  = size_t(cryptData!.length)
        
        //  可选 的初始化向量
        let viData :NSData = (iv as NSString).dataUsingEncoding(NSUTF8StringEncoding) as NSData!
        let viDataBytes    = UnsafeMutablePointer(viData.bytes)
        
        // 特定的几个参数
        let keyLength              = size_t(kCCKeySize3DES)
        let operation: CCOperation = UInt32(op)
        let algoritm:  CCAlgorithm = UInt32(kCCAlgorithm3DES)
        let options:   CCOptions   = UInt32(kCCOptionPKCS7Padding)
        
        var numBytesCrypted :size_t = 0
        
        let cryptStatus = CCCrypt(operation, // 加密还是解密
            algoritm, // 算法类型
            options,  // 密码块的设置选项
            keyBytes, // 秘钥的字节
            keyLength, // 秘钥的长度
            viDataBytes, // 可选初始化向量的字节
            dataBytes, // 加解密内容的字节
            dataLength, // 加解密内容的长度
            cryptPointer, // output data buffer
            cryptLength,  // output data length available
            &numBytesCrypted) // real output data length 
  
        
      
        if UInt32(cryptStatus) == UInt32(kCCSuccess) {
     
          cryptData!.length = Int(numBytesCrypted)
          if op == CCOperation(kCCEncrypt)  {
                let base64cryptString = cryptData!.base64EncodedStringWithOptions(.Encoding64CharacterLineLength)
                return base64cryptString
            }
            else {
           //   let base64cryptString = NSString(bytes: cryptPointer, length: cryptLength, encoding: NSUTF8StringEncoding) as? String  // 用这个会导致返回的JSON数据格式可能有问题,最好不用
                let base64cryptString = NSString(data: cryptData!,  encoding: NSUTF8StringEncoding) as? String
                return base64cryptString
            }
        } else {
            print("Error: \(cryptStatus)")
        }
        return nil
    }
    

}

补充:
CCOperation(操作)、CCAgorithm(算法) 和 CCOptions(设置)本质上就是 uint32_t(一个占32位存储的 unsigned int),所以我们可以通过 CommonCrypto 常量来构造它们。

let operation = CCOperation(kCCEncrypt)
let algorithm = CCAlgorithm(kCCAlgorithmAES) // 后面算法随你选择
let options = CCOptions(kCCOptionECBMode) // 设置项

附带一个Oc版的 3DES加解密 (此处没有用系统的base64,用的是GTMBase64)

+ (NSString*)TripleDES:(NSString*)plainText encryptOrDecrypt:(CCOperation)encryptOrDecrypt key:(NSString*)key {
    
    
    const void *vplainText;
    size_t plainTextBufferSize;
    
    if (encryptOrDecrypt == kCCDecrypt)
    {
        NSData *EncryptData = [GTMBase64 decodeData:[plainText dataUsingEncoding:NSUTF8StringEncoding]];
        plainTextBufferSize = [EncryptData length];
        vplainText = [EncryptData bytes];
    }
    else
    {
        NSData* data = [plainText dataUsingEncoding:NSUTF8StringEncoding];
        plainTextBufferSize = [data length];
        vplainText = (const void *)[data bytes];
    }
    
    CCCryptorStatus ccStatus;
    uint8_t *bufferPtr = NULL;
    size_t bufferPtrSize = 0;
    size_t movedBytes = 0;
 
    bufferPtrSize = (plainTextBufferSize + kCCBlockSize3DES) & ~(kCCBlockSize3DES - 1);
    bufferPtr = malloc( bufferPtrSize * sizeof(uint8_t));
    memset((void *)bufferPtr, 0x0, bufferPtrSize);
 
    NSString *initVec = @"p2p_s2iv";
    const void *vkey = (const void *) [key UTF8String];
    const void *vinitVec = (const void *) [initVec UTF8String];
    
    ccStatus = CCCrypt(encryptOrDecrypt,
                       kCCAlgorithm3DES,
                       kCCOptionPKCS7Padding,
                       vkey, //"123456789012345678901234", //key
                       kCCKeySize3DES,
                       vinitVec, //"init Vec", //iv,
                       vplainText, //"Your Name", //plainText,
                       plainTextBufferSize,
                       (void *)bufferPtr,
                       bufferPtrSize,
                       &movedBytes);

    
    NSString *result;
    
    if (encryptOrDecrypt == kCCDecrypt)
    {
        result = [[NSString alloc] initWithData:[NSData dataWithBytes:(const void *)bufferPtr
                                                                length:(NSUInteger)movedBytes]
                                        encoding:NSUTF8StringEncoding]
                  ;
    }
    else
    {
        NSData *myData = [NSData dataWithBytes:(const void *)bufferPtr length:(NSUInteger)movedBytes];
        result = [GTMBase64 stringByEncodingData:myData];
    }
    
    return result;
    
}

附带一个Swift 版的 Base64 + String

extension String {
    
    //Encode base64
    func base64Encoded() -> String {
        let plainData = self.dataUsingEncoding(NSUTF8StringEncoding)
        let base64String = plainData?.base64EncodedStringWithOptions(.Encoding64CharacterLineLength)
        return base64String!
    }
    
    //Decode base64
    func base64Decoded() -> String {
        let decodedData = NSData(base64EncodedString: self, options: .IgnoreUnknownCharacters)
        let decodedString = NSString(data: decodedData!, encoding: NSUTF8StringEncoding)
        return decodedString! as String
    }
}

MD5

MD5以512位分组来处理输入的信息,且每一分组又被划分为16个32位子分组,经过了一系列的处理后,算法的输出由四个32位分组组成,将这四个32位分组级联后将生成一个128位散列值。
MD5的典型应用是对一段Message(字节串)产生fingerprint(指纹),以防止被“篡改”。举个例子,你将一段话写在一个叫 readme.txt文件中,并对这个readme.txt产生一个MD5的值并记录在案,然后你可以传播这个文件给别人,别人如果修改了文件中的任何内容,你对这个文件重新计算MD5时就会发现。如果再有一个第三方的认证机构,用MD5还可以防止文件作者的“抵赖”,这就是所谓的数字签名应用。

swift + MD5

extension String  {
    var MD5: String! {
        let str = self.cStringUsingEncoding(NSUTF8StringEncoding)
        let strLen = CC_LONG(self.lengthOfBytesUsingEncoding(NSUTF8StringEncoding))
        let digestLen = Int(CC_MD5_DIGEST_LENGTH)
        let result = UnsafeMutablePointer.alloc(digestLen)
        
        CC_MD5(str!, strLen, result)
        
        let hash = NSMutableString()
        for i in 0..

Oc + MD5

// 注意导入
#import 
- (NSString *)MD5Hash
{
    const char *cStr = [self UTF8String];
    unsigned char result[16];
    CC_MD5(cStr, (unsigned)strlen(cStr), result);
    return [NSString stringWithFormat:
            @"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
            result[0], result[1], result[2], result[3], 
            result[4], result[5], result[6], result[7],
            result[8], result[9], result[10], result[11],
            result[12], result[13], result[14], result[15]];
}

一定要注意, Swift 剔除了 Objective-C 中属于 C 的部分,因此我们需要做一些准备工作才能在 Swift 和 Cocoa 中使用 CommonCrypto,我们需要在Bridging-Header.h 中加入#import

备注参考

http://www.cnblogs.com/yangywyangyw/archive/2012/07/31/2620861.html
http://stackoverflow.com/questions/25754147/issue-using-cccrypt-commoncrypt-in-swift
http://www.itupup.com/?it09/525141.htm

你可能感兴趣的:(iOS 中 3DES加密、MD5加密)