美文网首页iOS基本功加密和解密
iOS开发中DES的加密和解密

iOS开发中DES的加密和解密

作者: Andy_Livings | 来源:发表于2020-04-16 15:00 被阅读0次

    需要初始化iv的DES加密。(CBC模式)

    两个iv任选其一,必须要和你的后台对应。(CBC模式)
    const Byte iv[] = {1,2,3,4,5,6,7,8};
    const Byte iv[] = {0,1,2,3,4,5,6,7};

    /// 需要初始化iv的DES加密。(CBC模式)
    + (NSString *)encodeDesCBCWithString:(NSString*)stringCBC {
        
        NSData*data;
    //    NSString*ciphertext =nil;
        NSData *textData = [stringCBC dataUsingEncoding:NSUTF8StringEncoding];
        NSUInteger dataLength = [textData length];
        unsigned char buffer[1024];
        
        memset(buffer,0,sizeof(char));
        size_t numBytesEncrypted = 0;
        CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmDES,
                                              kCCOptionPKCS7Padding ,
                                              [kASDESKEY UTF8String],kCCKeySizeDES,
                                              iv,
                                              [textData bytes], dataLength,
                                              buffer,1024,
                                              &numBytesEncrypted);
        
        if(cryptStatus ==kCCSuccess) {
            
            data = [NSData dataWithBytes:buffer length:(NSUInteger)numBytesEncrypted];
        }
        
        NSString *result = [data base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
        
        return result;
        
    }
    

    需要初始化iv的DES解密。(CBC模式)

    /// 需要初始化iv的DES解密。(CBC模式)
    + (NSString*)decodeDesCBCWithString:(NSString *)stringCBC {
        
    //    NSData*plaindata =nil;
        NSString*plaintext =nil;
        //    NSData *cipherdata = [GTMBase64 decodeString:stringCBC];
        NSData *cipherdata = [[NSData alloc] initWithBase64EncodedString:stringCBC options:NSDataBase64DecodingIgnoreUnknownCharacters];
        unsigned char buffer[1024];
        
        memset(buffer,0,sizeof(char));
        size_t numBytesDecrypted = 0;
        CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmDES,
                                              kCCOptionPKCS7Padding ,
                                              [kASDESKEY UTF8String],kCCKeySizeDES,
                                              iv,
                                              [cipherdata bytes], [cipherdata length],
                                              buffer,1024,
                                              &numBytesDecrypted);
        
        if (cryptStatus ==kCCSuccess) {
            
            NSData*plaindata = [NSData dataWithBytes:buffer length:(NSUInteger)numBytesDecrypted];
            plaintext = [[NSString alloc]initWithData:plaindata encoding:NSUTF8StringEncoding];
            
        }
        
        return plaintext;
        
    }
    

    不需要初始化iv的DES加密。(ECB模式)

    /// 不需要初始化iv的DES加密。(ECB模式)
    + (NSString *)encodeDesECBWithString:(NSString*)stringECB {
        
        NSData*data;
    //    NSString*ciphertext =nil;
        NSData *textData = [stringECB dataUsingEncoding:NSUTF8StringEncoding];
        NSUInteger dataLength = [textData length];
        unsigned char buffer[1024];
        
        memset(buffer,0,sizeof(char));
        size_t numBytesEncrypted = 0;
        CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmDES,
                                              kCCOptionPKCS7Padding | kCCOptionECBMode,
                                              [kASDESKEY UTF8String],kCCKeySizeDES,
                                              NULL,
                                              [textData bytes], dataLength,
                                              buffer,1024,
                                              &numBytesEncrypted);
        if(cryptStatus ==kCCSuccess) {
            
            data = [NSData dataWithBytes:buffer length:(NSUInteger)numBytesEncrypted];
        }
        
        NSString *result = [data base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
        
        return result;
        
    }
    

    不需要初始化iv的DES解密。(ECB模式)

    /// 不需要初始化iv的DES解密。(ECB模式)
    + (NSString*)decodeDesECBWithString:(NSString *)stringECB {
        
    //    NSData*plaindata = nil;
        NSString*plaintext = nil;
        //    NSData *cipherdata = [GTMBase64 decodeString:stringECB];
        NSData *cipherdata = [[NSData alloc] initWithBase64EncodedString:stringECB options:NSDataBase64DecodingIgnoreUnknownCharacters];
        unsigned char buffer[1024];
        
        memset(buffer,0,sizeof(char));
        size_t numBytesDecrypted = 0;
        CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmDES,
                                              kCCOptionPKCS7Padding | kCCOptionECBMode,
                                              [kASDESKEY UTF8String],kCCKeySizeDES,
                                              NULL,
                                              [cipherdata bytes], [cipherdata length],
                                              buffer,1024,
                                              &numBytesDecrypted);
        
        if (cryptStatus == kCCSuccess) {
            
            NSData*plaindata = [NSData dataWithBytes:buffer length:(NSUInteger)numBytesDecrypted];
            plaintext = [[NSString alloc]initWithData:plaindata encoding:NSUTF8StringEncoding];
        }
        return plaintext;
    }
    

    DES16进制加密

    /// 使用DES加密方法
    + (NSString *)encodeDesWithString:(NSString *)string {
        NSString *ciphertext = nil;
        const char *textBytes = [string UTF8String];
        size_t dataLength = [string length];
        //==================
        
        uint8_t *bufferPtr = NULL;
        size_t bufferPtrSize = 0;
        size_t movedBytes = 0;
        
        bufferPtrSize = (dataLength + kCCBlockSizeDES) & ~(kCCBlockSizeDES - 1);
        bufferPtr = malloc( bufferPtrSize * sizeof(uint8_t));
        memset((void *)bufferPtr, 0x0, bufferPtrSize);
        
        
        NSString *testString = kASDESKEY;
        NSData *testData = [testString dataUsingEncoding: NSUTF8StringEncoding];
        Byte *iv = (Byte *)[testData bytes];
        
        
        CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmDES,
                                              kCCOptionPKCS7Padding,
                                              [kASDESKEY UTF8String], kCCKeySizeDES,
                                              iv,
                                              textBytes, dataLength,
                                              (void *)bufferPtr, bufferPtrSize,
                                              &movedBytes);
        if (cryptStatus == kCCSuccess) {
            
            ciphertext= [ASKDESTools parseByte2HexString:bufferPtr :(int)movedBytes];
    
        }
        ciphertext=[ciphertext uppercaseString];//字符变大写
        
        return ciphertext;
    }
    

    DES16进制解密

    /// 使用DES进行解密计算
    + (NSString *)decodeDesWithString:(NSString *)string {
        
        NSData* cipherData = [ASKDESTools convertHexStrToData:[string lowercaseString]];
        
        unsigned char buffer[1024];
        memset(buffer, 0, sizeof(char));
        size_t numBytesDecrypted = 0;
        NSString *testString = kASDESKEY;
        NSData *testData = [testString dataUsingEncoding: NSUTF8StringEncoding];
        Byte *iv = (Byte *)[testData bytes];
        CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt,
                                              kCCAlgorithmDES,
                                              kCCOptionPKCS7Padding,
                                              [kASDESKEY UTF8String],
                                              kCCKeySizeDES,
                                              iv,
                                              [cipherData bytes],
                                              [cipherData length],
                                              buffer,
                                              1024,
                                              &numBytesDecrypted);
        NSString* plainText = nil;
        if (cryptStatus == kCCSuccess) {
            NSData* data = [NSData dataWithBytes:buffer length:(NSUInteger)numBytesDecrypted];
            plainText = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
        }
        return plainText;
    
    }
    

    加密解密中有两个方法调用,其实是为了16进制与data之间的转换。有些公司并未转换成16进制,而是需要跟base64共同加解密。方法适用,只需要将得出的plainText 的值转成base64即可。

    加密时转成16进制

    + (NSString *) parseByte2HexString:(Byte *) bytes  :(int)len {
        
        
        NSString *hexStr = @"";
        
        if(bytes)
        {
            for(int i = 0; i < len ; 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];
                }
                
            }
        }
        
        return hexStr;
    }
    

    解密时转回data

    + (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;
        }
        
        return hexData;
    }
    

    注意:
    1、DES的加密模式有ECB和CBC。
    2、iOS的填充模式只有 kCCOptionPKCS7Padding 和kCCOptionPKCS7Padding | kCCOptionECBMode两种。而后台填充模式就多了,这就需要一一对应才能实现加密和解密。
    3、具体的对应模式是java的DES/ECB/PKCS5Padding对应iOS的kCCOptionPKCS7Padding | kCCOptionECBMode;DES/CBC/PKCS5Padding对应ios的kCCOptionPKCS7Padding 。

    Simulator Screen Shot - iPhone 11 Pro Max - 2020-04-30 at 16.17.14.png

    Demo下载地址

    相关文章

      网友评论

        本文标题:iOS开发中DES的加密和解密

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