swift DES-ECB 加密解密仅供参考

2020-04-02  本文已影响0人  舟_e9ce

记录一下DES-ECB加密解密。
加密解密用到的工具NSData+DataToString.h

@interface NSData (DataToString)

-(NSString *)convertedToUtf8String;

- (NSData *)replaceNoUtf8:(NSData *)data;

- (NSString *)hexStringFromData:(NSData *)myD;

@end

NSData+DataToString.m

@implementation NSData (DataToString)

-(NSString *)convertedToUtf8String{
    
    NSString *string = [[NSString alloc] initWithData:self encoding:NSUTF8StringEncoding];
    if (string == nil) {
        string = [[NSString alloc] initWithData:[self UTF8Data] encoding:NSUTF8StringEncoding];
    }
    return string;
    
}

-(NSData *)UTF8Data {
    
    //保存结果
    NSMutableData *resData = [[NSMutableData alloc] initWithCapacity:self.length];
    
    NSData *replacement = [@"12" dataUsingEncoding:NSUTF8StringEncoding];
    
    uint64_t index = 0;
    const uint8_t *bytes = self.bytes;
    
    long dataLength = (long) self.length;
    
    while (index < dataLength) {
        uint8_t len = 0;
        uint8_t firstChar = bytes[index];
        
        // 1个字节
        if ((firstChar & 0x80) == 0 && (firstChar == 0x09 || firstChar == 0x0A || firstChar == 0x0D || (0x20 <= firstChar && firstChar <= 0x7E))) {
            len = 1;
        }
        // 2字节
        else if ((firstChar & 0xE0) == 0xC0 && (0xC2 <= firstChar && firstChar <= 0xDF)) {
            if (index + 1 < dataLength) {
                uint8_t secondChar = bytes[index + 1];
                if (0x80 <= secondChar && secondChar <= 0xBF) {
                    len = 2;
                }
            }
        }
        // 3字节
        else if ((firstChar & 0xF0) == 0xE0) {
            if (index + 2 < dataLength) {
                uint8_t secondChar = bytes[index + 1];
                uint8_t thirdChar = bytes[index + 2];
                
                if (firstChar == 0xE0 && (0xA0 <= secondChar && secondChar <= 0xBF) && (0x80 <= thirdChar && thirdChar <= 0xBF)) {
                    len = 3;
                } else if (((0xE1 <= firstChar && firstChar <= 0xEC) || firstChar == 0xEE || firstChar == 0xEF) && (0x80 <= secondChar && secondChar <= 0xBF) && (0x80 <= thirdChar && thirdChar <= 0xBF)) {
                    len = 3;
                } else if (firstChar == 0xED && (0x80 <= secondChar && secondChar <= 0x9F) && (0x80 <= thirdChar && thirdChar <= 0xBF)) {
                    len = 3;
                }
            }
        }
        // 4字节
        else if ((firstChar & 0xF8) == 0xF0) {
            if (index + 3 < dataLength) {
                uint8_t secondChar = bytes[index + 1];
                uint8_t thirdChar = bytes[index + 2];
                uint8_t fourthChar = bytes[index + 3];
                
                if (firstChar == 0xF0) {
                    if ((0x90 <= secondChar & secondChar <= 0xBF) && (0x80 <= thirdChar && thirdChar <= 0xBF) && (0x80 <= fourthChar && fourthChar <= 0xBF)) {
                        len = 4;
                    }
                } else if ((0xF1 <= firstChar && firstChar <= 0xF3)) {
                    if ((0x80 <= secondChar && secondChar <= 0xBF) && (0x80 <= thirdChar && thirdChar <= 0xBF) && (0x80 <= fourthChar && fourthChar <= 0xBF)) {
                        len = 4;
                    }
                } else if (firstChar == 0xF3) {
                    if ((0x80 <= secondChar && secondChar <= 0x8F) && (0x80 <= thirdChar && thirdChar <= 0xBF) && (0x80 <= fourthChar && fourthChar <= 0xBF)) {
                        len = 4;
                    }
                }
            }
        }
        // 5个字节
        else if ((firstChar & 0xFC) == 0xF8) {
            len = 0;
        }
        // 6个字节
        else if ((firstChar & 0xFE) == 0xFC) {
            len = 0;
        }
        
        if (len == 0) {
            index++;
            [resData appendData:replacement];
        } else {
            [resData appendBytes:bytes + index length:len];
            index += len;
        }
    }
    
    return resData;
    
}


//注意:如果是三字节utf-8,第二字节错误,则先替换第一字节内容(认为此字节误码为三字节utf8的头),然后判断剩下的两个字节是否非法;
- (NSData *)replaceNoUtf8:(NSData *)data
{
    char aa[] = {'A','A','A','A','A','A'};                      //utf8最多6个字符,当前方法未使用
    NSMutableData *md = [NSMutableData dataWithData:data];
    int loc = 0;
    while(loc < [md length])
    {
        char buffer;
        [md getBytes:&buffer range:NSMakeRange(loc, 1)];
        if((buffer & 0x80) == 0)
        {
            loc++;
            continue;
        }
        else if((buffer & 0xE0) == 0xC0)
        {
            loc++;
            [md getBytes:&buffer range:NSMakeRange(loc, 1)];
            if((buffer & 0xC0) == 0x80)
            {
                loc++;
                continue;
            }
            loc--;
            //非法字符,将这个字符(一个byte)替换为A
            [md replaceBytesInRange:NSMakeRange(loc, 1) withBytes:aa length:1];
            loc++;
            continue;
        }
        else if((buffer & 0xF0) == 0xE0)
        {
            loc++;
            [md getBytes:&buffer range:NSMakeRange(loc, 1)];
            if((buffer & 0xC0) == 0x80)
            {
                loc++;
                [md getBytes:&buffer range:NSMakeRange(loc, 1)];
                if((buffer & 0xC0) == 0x80)
                {
                    loc++;
                    continue;
                }
                loc--;
            }
            loc--;
            //非法字符,将这个字符(一个byte)替换为A
            [md replaceBytesInRange:NSMakeRange(loc, 1) withBytes:aa length:1];
            loc++;
            continue;
        }
        else
        {
            //非法字符,将这个字符(一个byte)替换为A
            [md replaceBytesInRange:NSMakeRange(loc, 1) withBytes:aa length:1];
            loc++;
            continue;
        }
    }
      
    return md;
}

//data转换为十六进制的string
- (NSString *)hexStringFromData:(NSData *)myD{
    
    Byte *bytes = (Byte *)[myD bytes];
    //下面是Byte 转换为16进制。
    NSString *hexStr=@"";
    for(int i=0;i<[myD length];i++)
        
    {
        NSString *newHexStr = [NSString stringWithFormat:@"%x",bytes[i]&0xff];///16进制数
        
        if([newHexStr length]==1)
            
            hexStr = [NSString stringWithFormat:@"%@0%@",hexStr,newHexStr];
        
        else
            
            hexStr = [NSString stringWithFormat:@"%@%@",hexStr,newHexStr];
    }
    NSLog(@"hex = %@",hexStr);
    
    return hexStr;
}
@end

字符串转NSData,系统自带的不好用,会出现解密后数据为空,(我这里用的时候是这样的)
此方法可以单独去封装只是一个工具,借鉴别的大神的,用在获取到后台返回数据后,解密前

// MARK: 获取到的字符串转成NSData
- (NSData *)convertHexStrToData:(NSString *)str {
    if (!str || [str length] == 0) {
        return nil;
    }
    
    NSMutableData *hexData = [[NSMutableData alloc] initWithCapacity:8];
    NSRange range;
    if ([str length] % 2 == 0) {
        range = NSMakeRange(0, 2);
    } else {
        range = NSMakeRange(0, 1);
    }
    for (NSInteger i = range.location; i < [str length]; i += 2) {
        unsigned int anInt;
        NSString *hexCharStr = [str substringWithRange:range];
        NSScanner *scanner = [[NSScanner alloc] initWithString:hexCharStr];
        
        [scanner scanHexInt:&anInt];
        NSData *entity = [[NSData alloc] initWithBytes:&anInt length:1];
        [hexData appendData:entity];
        
        range.location += range.length;
        range.length = 2;
    }
    
    NSLog(@"hexdata: %@", hexData);
    return hexData;
}

封装后调用方法

// MARK: 加密
    static func encrypotion(key:String,content:String) -> String {
        let keyString = key
        let keyData : NSData! = (keyString.data(using: String.Encoding.utf8)! as NSData)
        let message = content
        let data:NSData! = (message.data(using: String.Encoding.utf8)! as NSData)
        print("要加密的字符串:" + message)
        // 下边时进行加密解密的代码
//                let result:NSData? = data.AES128Crypt(operation: CCOperation(kCCEncrypt), keyData: keyData)
        //        print("encrypt = \(result!)")
        //        let oldData = result?.AES128Crypt(operation: CCOperation(kCCDecrypt), keyData: keyData)
        //        print("decrypt = \(oldData!)")
        //        print(String(data: oldData as! Data, encoding: String.Encoding.utf8)!)
        
        // 下边是进行加密的数据
        let enData = data.enCrypt(algorithm: .DES, keyData: keyData)
        let str = enData.hexString(from: enData as Data)
        return str
    
    }
   
    
    // MARK: 解密
    static func decryption(key:String, enData:String) -> [String:Any] {

        let keyString = key
        let keyData : NSData! = (keyString.data(using: String.Encoding.utf8)! as NSData)

        let nsData : NSData = DesECB().convertHexStr(toData: enData) as NSData
        // 下边是进行解密的数据
        let deData : NSData = nsData.deCrypt(algorithm: .DES, keyData: keyData)!
        
        print("解析数据 \(String(data: deData as Data, encoding: String.Encoding.utf8)!)")
        if let dict = try? JSONSerialization.jsonObject(with: deData as Data, options: JSONSerialization.ReadingOptions.mutableContainers) as? [String : Any] {
            print(dict)
            return dict!
        }
        return [:]
    }

加密解密具体方法 swift 版

import UIKit


enum CryptoAlgorithm {
    case AES,AES128,DES,DES3,CAST,RC2,RC4,Blowfish
    var algorithm : CCAlgorithm {
        var result : UInt32 = 0
        switch self {
        case .AES:
            result = UInt32(kCCAlgorithmAES)
        case .AES128:
            result = UInt32(kCCAlgorithmAES128)
        case .DES:
            result = UInt32(kCCAlgorithmDES)
        case .DES3:
            result = UInt32(kCCAlgorithm3DES)
        case .CAST:
            result = UInt32(kCCAlgorithmCAST)
        case .RC2:
            result = UInt32(kCCAlgorithmRC2)
        case .RC4:
            result = UInt32(kCCAlgorithmRC4)
        case .Blowfish:
            result = UInt32(kCCAlgorithmBlowfish)
        }
        return CCAlgorithm(result)
    }
    
    var keyLength : Int {
        var result : Int = 0
        switch self {
        case .AES:
            result = kCCKeySizeAES128
        case .AES128:
            result = kCCKeySizeAES256
        case .DES:
            result = kCCKeySizeDES
        case .DES3:
            result = kCCKeySize3DES
        case .CAST:
            result = kCCKeySizeMaxCAST
        case .RC2:
            result = kCCKeySizeMaxRC2
        case .RC4:
            result = kCCKeySizeMaxRC4
        case .Blowfish:
            result = kCCKeySizeMaxBlowfish
        }
        return Int(result)
    }
    
    var cryptLength:Int {
        var result:Int = 0
        switch self {
        case .AES:
            result = kCCKeySizeAES128
        case .AES128:
            result = kCCBlockSizeAES128
        case .DES:
            result = kCCBlockSizeDES
        case .DES3:
            result = kCCBlockSize3DES
        case .CAST:
            result = kCCBlockSizeCAST
        case .RC2:
            result = kCCBlockSizeRC2
        case .RC4:
            result = kCCBlockSizeRC2
        case .Blowfish:
            result = kCCBlockSizeBlowfish
        }
        return Int(result)
    }
    
}

extension NSData {
    /**
     加密
     - parameter algorithm:加密方式
     - parameter keyData:加密key
     - return NSData :加密后的数据
     */
    func enCrypt(algorithm:CryptoAlgorithm,keyData:NSData) -> NSData {
        return crypt(algorithm: algorithm, operation: CCOperation(kCCEncrypt), keyData: keyData)!
    }
    
    /// 解密
    /// - Parameters:
    ///   - algorithm: 解密方式
    ///   - keyData: 解密key
    func deCrypt(algorithm:CryptoAlgorithm,keyData:NSData) -> NSData? {
        return crypt(algorithm: algorithm, operation: CCOperation(kCCDecrypt), keyData: keyData)
    }
    
    
    func crypt(algorithm:CryptoAlgorithm,operation:CCOperation,keyData:NSData) -> NSData? {
        let keyBytes = keyData.bytes
        let keyLength = Int(algorithm.keyLength)
        let datalength = self.length
        let dataBytes = self.bytes
        let cryptLength = Int(datalength + algorithm.cryptLength)
        let cryptPointer = UnsafeMutablePointer<UInt8>.allocate(capacity: cryptLength)
        let algoritm: CCAlgorithm = CCAlgorithm(algorithm.algorithm)
        let option: CCOptions = CCOptions(kCCOptionECBMode + kCCOptionPKCS7Padding)
        let numBytesEncrypted = UnsafeMutablePointer<Int>.allocate(capacity: 1)
        numBytesEncrypted.initialize(to: 0)
        let cryptStatus = CCCrypt(operation, algoritm, option, keyBytes, keyLength, nil, dataBytes, datalength, cryptPointer, cryptLength, numBytesEncrypted)
        
        
        // 判断是否加密成功
        if CCStatus(cryptStatus) == CCStatus(kCCSuccess) {
            let len = Int(numBytesEncrypted.pointee)
            let data:NSData = NSData(bytesNoCopy: cryptPointer, length: len)
            numBytesEncrypted.deallocate()
            return data
        } else {
            numBytesEncrypted.deallocate()
            cryptPointer.deallocate()
            return nil
        }
    }
}

上一篇下一篇

猜你喜欢

热点阅读