美文网首页
swift DES-ECB 加密解密仅供参考

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

作者: 舟_e9ce | 来源:发表于2020-04-02 10:34 被阅读0次

    记录一下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
            }
        }
    }
    
    

    相关文章

      网友评论

          本文标题:swift DES-ECB 加密解密仅供参考

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