• 使用 DES 算法对数据加密


    DES算法

    ☆提供高质量的数据保护,防止数据未经授权的泄露和未被察觉的修改

    ☆具有相当高的复杂性,使得破译的开销超过可能获得的利益,同时又要便于理解和掌握

    ☆DES密码体制的安全性应该不依赖于算法的保密,其安全性仅以加密密钥的保密为基础

    ☆实现经济,运行有效,并且适用于多种完全不同的应用

    苹果本身支持DES加密,在项目中引入头文件 CommonCrypto/CommonCryptor.h 即可使用相关函数.

    我自己对其进行了封装,支持ARC与非ARC

    YXCrypto.h

    //
    //  YXCrypto.h
    //  用秘钥给字符串加密或者解密
    //
    //  Created by YouXian on 14-3-18.
    //  Copyright (c) 2014年 YouXian. All rights reserved.
    //
    
    #import <Foundation/Foundation.h>
    
    @interface YXCrypto : NSObject
    
    /*!
     * 给字符串加密
     */
    + (NSString *)DesEncryptString:(NSString*)src WithKey:(NSString *)key;
    
    /*!
     * 给字符串解密
     */
    + (NSString *)DesDecryptString:(NSString*)src WithKey:(NSString *)key;
    
    @end

    YXCrypto.m

    //
    //  YXCrypto.m
    //  用秘钥给字符串加密或者解密
    //
    //  Created by YouXian on 14-3-18.
    //  Copyright (c) 2014年 YouXian. All rights reserved.
    //
    
    #import "YXCrypto.h"
    #import <CommonCrypto/CommonCryptor.h>
    
    #if __has_feature(objc_arc)
    // ARC
    #define Auto_Release(obj)
    #define Safe_Release(obj)
    #else
    // 非ARC
    #define Auto_Release(obj) [obj autorelease]
    #define Safe_Release(obj) [obj release]; obj = nil
    #endif
    
    static YXCrypto *shareInstance = nil;
    
    @implementation YXCrypto
    
    /*!
     * 给字符串加密
     */
    + (NSString *)DesEncryptString:(NSString*)src WithKey:(NSString *)key {
        NSString* strRet = @"";
        
        if (shareInstance == nil)
        {
            shareInstance = [[YXCrypto alloc] init];
        }
        
        // encrypt source content
        NSData* bytes = [src dataUsingEncoding:NSUTF8StringEncoding];
        NSData* data = [shareInstance DesCryptWithOperation:kCCEncrypt
                                                      bytes:bytes
                                                        key:key];
        
        // format bytes to visible string
        char* pBuff = (char*)[data bytes];
        for (int i=0; i<data.length; i++) {
            strRet = [strRet stringByAppendingFormat:@"%02X", pBuff[i]& 0xFF];
        }
        return strRet;
    }
    
    /*!
     * 给字符串解密
     */
    + (NSString *)DesDecryptString:(NSString*)src WithKey:(NSString *)key
    {
        if (shareInstance == nil)
        {
            shareInstance = [[YXCrypto alloc] init];
        }
        
        static unsigned char _map_ch2hex[] =
        {
            0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
            0, 0, 0, 0, 0, 0, 0,    // :, ;, <, =, >, ?, @,
            0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
        };
        
        // decode source content to bytes
        unsigned char* bytes = (unsigned char*)malloc((src.length+1)*sizeof(unsigned char));
        [[src uppercaseString] getCString:(char*)bytes maxLength:src.length+1 encoding:NSUTF8StringEncoding];
        unsigned char *p1 = bytes, *p2 = bytes;
        int n = src.length/2;
        for (int i=0; i<n; i++) {
            *p1 = _map_ch2hex[*p2-'0'] * 0x10 + _map_ch2hex[*(p2+1)-'0'];
            p1++;
            p2+=2;
        }
        NSData* data = [NSData dataWithBytes:bytes
                                      length:n];
        
        // decrypt source bytes
        NSData* dataOut = [shareInstance DesCryptWithOperation:kCCDecrypt
                                                         bytes:data
                                                           key:key];
        free(bytes);
        
        NSString* strRet = [[NSString alloc] initWithData:dataOut
                                                 encoding:NSUTF8StringEncoding];
        Auto_Release(strRet);
        
        return strRet;
    }
    
    - (NSData *)DesCryptWithOperation:(CCOperation)operation bytes:(NSData*)bytes key:(NSString *)key {
        
        NSUInteger dataLength = [bytes length];
        
        size_t bufferSize = ([bytes length] + kCCBlockSizeDES) & ~(kCCBlockSizeDES - 1);
        unsigned char *buffer = (unsigned char *)malloc(bufferSize*sizeof(unsigned char));
        memset((void*)buffer, 0, bufferSize);
        
        size_t numBytesCrypted = 0;
        CCCryptorStatus cryptStatus = CCCrypt(operation,
                                              kCCAlgorithmDES,
                                              kCCOptionPKCS7Padding | kCCOptionECBMode,
                                              (void const*)[key UTF8String],
                                              kCCKeySizeDES,
                                              NULL,
                                              [bytes bytes], dataLength,
                                              (void*)buffer, bufferSize,
                                              &numBytesCrypted);
        NSData* dataRet = nil;
        if (cryptStatus == kCCSuccess) {
            dataRet = [[NSData alloc] initWithBytes:buffer length:numBytesCrypted];
            Auto_Release(dataRet);
        }
        free(buffer);
        return dataRet;
    }
    
    @end

    使用:

    附录1:https://github.com/alfaromeodev/Cryptor

    //
    //  Cryptor.h
    //  test
    //
    //  Created by Da Zhang on 11/5/12.
    //  Copyright 2012 __MyCompanyName__. All rights reserved.
    //
    
    #import <Foundation/Foundation.h>
    #import <CommonCrypto/CommonDigest.h>
    #import <CommonCrypto/CommonCryptor.h>
    
    
    @interface Cryptor : NSObject {
        
    }
    
    /*
     all the methods below only support utf8 string
     */
    + (NSString *)encodeMD5:(NSString *)str;
    
    + (NSString *)encodeDES:(NSString *)plainString key:(NSString *)key;
    + (NSString *)decodeDES:(NSString *)decodedString key:(NSString*)key;
    
    + (NSString *)encodeBase64:(NSString *)plainString;
    + (NSString *)decodeBase64:(NSString *)decodedString;
    
    @end
    //
    //  Cryptor.m
    //  test
    //
    //  Created by Da Zhang on 11/5/12.
    //  Copyright 2012 __MyCompanyName__. All rights reserved.
    //
    
    #import "Cryptor.h"
    
    @interface Cryptor ()
    
    + (NSString *)encodeBase64WithData:(NSData *)objData;
    + (NSData *)decodeBase64WithUTF8String:(NSString *)strBase64;
    + (NSString *)parseByte2HexString:(Byte *)bytes;
    
    @end
    
    
    static const char _base64EncodingTable[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
    static const short _base64DecodingTable[256] = {
        -2, -2, -2, -2, -2, -2, -2, -2, -2, -1, -1, -2, -1, -1, -2, -2,
        -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
        -1, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, 62, -2, -2, -2, 63,
        52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -2, -2, -2, -2, -2, -2,
        -2,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
        15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -2, -2, -2, -2, -2,
        -2, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
        41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -2, -2, -2, -2, -2,
        -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
        -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
        -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
        -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
        -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
        -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
        -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
        -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2
    };
    
    
    @implementation Cryptor
    
    
    #pragma mark private section
    + (NSData *)decodeBase64WithUTF8String:(NSString *)strBase64 {
        const char * objPointer = [strBase64 cStringUsingEncoding:NSUTF8StringEncoding];
        int intLength = strlen(objPointer);
        int intCurrent;
        int i = 0, j = 0, k;
    
        unsigned char * objResult;
        objResult = calloc(intLength, sizeof(char));
    
        // Run through the whole string, converting as we go
        while ( ((intCurrent = *objPointer++) != '') && (intLength-- > 0) ) {
            if (intCurrent == '=') {
                if (*objPointer != '=' && ((i % 4) == 1)) {// || (intLength > 0)) {
                    // the padding character is invalid at this point -- so this entire string is invalid
                    free(objResult);
                    return nil;
                }
                continue;
            }
    
            intCurrent = _base64DecodingTable[intCurrent];
            if (intCurrent == -1) {
                // we're at a whitespace -- simply skip over
                continue;
            } else if (intCurrent == -2) {
                // we're at an invalid character
                free(objResult);
                return nil;
            }
    
            switch (i % 4) {
                case 0:
                    objResult[j] = intCurrent << 2;
                    break;
    
                case 1:
                    objResult[j++] |= intCurrent >> 4;
                    objResult[j] = (intCurrent & 0x0f) << 4;
                    break;
    
                case 2:
                    objResult[j++] |= intCurrent >>2;
                    objResult[j] = (intCurrent & 0x03) << 6;
                    break;
    
                case 3:
                    objResult[j++] |= intCurrent;
                    break;
            }
            i++;
        }
    
        // mop things up if we ended on a boundary
        k = j;
        if (intCurrent == '=') {
            switch (i % 4) {
                case 1:
                    // Invalid state
                    free(objResult);
                    return nil;
    
                case 2:
                    k++;
                    // flow through
                case 3:
                    objResult[k] = 0;
            }
        }
    
        // Cleanup and setup the return NSData
        NSData * objData = [[[NSData alloc] initWithBytes:objResult length:j] autorelease];
        free(objResult);
        return objData;
    }
    
    + (NSString *)encodeBase64WithData:(NSData *)objData {
        const unsigned char * objRawData = [objData bytes];
        char * objPointer;
        char * strResult;
    
        // Get the Raw Data length and ensure we actually have data
        int intLength = [objData length];
        if (intLength == 0) return nil;
    
        // Setup the String-based Result placeholder and pointer within that placeholder
        strResult = (char *)calloc(((intLength + 2) / 3) * 4, sizeof(char));
        objPointer = strResult;
    
        // Iterate through everything
        while (intLength > 2) { // keep going until we have less than 24 bits
            *objPointer++ = _base64EncodingTable[objRawData[0] >> 2];
            *objPointer++ = _base64EncodingTable[((objRawData[0] & 0x03) << 4) + (objRawData[1] >> 4)];
            *objPointer++ = _base64EncodingTable[((objRawData[1] & 0x0f) << 2) + (objRawData[2] >> 6)];
            *objPointer++ = _base64EncodingTable[objRawData[2] & 0x3f];
    
            // we just handled 3 octets (24 bits) of data
            objRawData += 3;
            intLength -= 3;
        }
    
        // now deal with the tail end of things
        if (intLength != 0) {
            *objPointer++ = _base64EncodingTable[objRawData[0] >> 2];
            if (intLength > 1) {
                *objPointer++ = _base64EncodingTable[((objRawData[0] & 0x03) << 4) + (objRawData[1] >> 4)];
                *objPointer++ = _base64EncodingTable[(objRawData[1] & 0x0f) << 2];
                *objPointer++ = '=';
            } else {
                *objPointer++ = _base64EncodingTable[(objRawData[0] & 0x03) << 4];
                *objPointer++ = '=';
                *objPointer++ = '=';
            }
        }
    
        // Terminate the string-based result
        *objPointer = '';
    
        // Return the results as an NSString object
        return [NSString stringWithCString:strResult encoding:NSUTF8StringEncoding];
    }
    
    + (NSString *)parseByte2HexString:(Byte *)bytes {
        NSMutableString *hexStr = [[NSMutableString alloc]init];
        int i = 0;
        if(bytes) {
            while (bytes[i] != '') {
                NSString *hexByte = [NSString stringWithFormat:@"%x",bytes[i] & 0xff];///16进制数
                if([hexByte length]==1) [hexStr appendFormat:@"0%@", hexByte];
                else [hexStr appendFormat:@"%@", hexByte];
                i++;
            }
        }
        //NSLog(@"bytes 的16进制数为:%@",hexStr);
        return hexStr;
    }
    
    
    #pragma mark public section
    + (NSString *)encodeMD5:(NSString *)str {
    
        const char *cStr = [str UTF8String];
    
        unsigned char result[CC_MD5_DIGEST_LENGTH];
    
        CC_MD5( cStr, 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]
    
                ];
    
    }
    
    + (NSString *)encodeBase64:(NSString *)plainString {
        return [Cryptor encodeBase64WithData:[plainString dataUsingEncoding:NSUTF8StringEncoding]];
    }
    
    + (NSString *)decodeBase64:(NSString *)decodedString {
        NSData * objData = [Cryptor decodeBase64WithUTF8String:decodedString];
        return [[NSString alloc] initWithData:objData encoding:NSUTF8StringEncoding];
    }
    
    + (NSString *)encodeDES:(NSString *)plainString key:(NSString *)key {
        NSString *ciphertext = nil;
        const char *textBytes = [plainString UTF8String];
        NSUInteger dataLength = strlen(textBytes);
        unsigned char buffer[1024];
        memset(buffer, 0, sizeof(char));
        Byte iv[] = {1,2,3,4,5,6,7,8};
        size_t numBytesEncrypted = 0;
        CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,
                                              kCCAlgorithmDES,
                                              kCCOptionPKCS7Padding,
                                              [key UTF8String],
                                              kCCKeySizeDES,
                                              iv,
                                              textBytes,
                                              dataLength,
                                              buffer,
                                              1024,
                                              &numBytesEncrypted);
        if (cryptStatus == kCCSuccess) {
            NSData *data = [NSData dataWithBytes:buffer length:(NSUInteger)numBytesEncrypted];
            ciphertext = [[Cryptor encodeBase64WithData:data] autorelease];
        }
        return ciphertext;
    }
    
    + (NSString *)decodeDES:(NSString*)decodedString key:(NSString*)key {
        NSData* cipherData = [Cryptor decodeBase64WithUTF8String:decodedString];
        unsigned char buffer[1024];
        memset(buffer, 0, sizeof(char));
        size_t numBytesDecrypted = 0;
        Byte iv[] = {1,2,3,4,5,6,7,8};
        CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt,
                                              kCCAlgorithmDES,
                                              kCCOptionPKCS7Padding,
                                              [key 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] autorelease];
        }
        return plainText;
    }
    
    @end

    附录2:AES加密

    NSData+AES.h + NSData+AES.m

    #import <Foundation/Foundation.h>
    
    /**
     * Adds AES encryption and decryption capabilities to NSData.
     */
    @interface NSData (AES)
    
    /**
     * Encrypt NSData using AES256 with a given symmetric encryption key.
     * @param key The symmetric encryption key
     */
    - (NSData *)AES256EncryptWithKey:(NSString *)key;
    
    /**
     * Decrypt NSData using AES256 with a given symmetric encryption key.
     * @param key The symmetric encryption key
     */
    - (NSData *)AES256DecryptWithKey:(NSString *)key;
    
    @end
    #import "NSData+AES.h"
    #import <CommonCrypto/CommonCryptor.h>
    
    @implementation NSData (AES)
    
    - (NSData *)AES256EncryptWithKey:(NSString *)key
    {
        // 'key' should be 32 bytes for AES256, will be null-padded otherwise
        char keyPtr[kCCKeySizeAES256+1]; // room for terminator (unused)
        bzero(keyPtr, sizeof(keyPtr)); // fill with zeroes (for padding)
        
        // fetch key data
        [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
        
        NSUInteger dataLength = [self length];
        
        //See the doc: For block ciphers, the output size will always be less than or
        //equal to the input size plus the size of one block.
        //That's why we need to add the size of one block here
        size_t bufferSize = dataLength + kCCBlockSizeAES128;
        void *buffer = malloc(bufferSize);
        
        size_t numBytesEncrypted = 0;
        CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding,
                                              keyPtr, kCCKeySizeAES256,
                                              NULL /* initialization vector (optional) */,
                                              [self bytes], dataLength, /* input */
                                              buffer, bufferSize, /* output */
                                              &numBytesEncrypted);
        if (cryptStatus == kCCSuccess) {
            //the returned NSData takes ownership of the buffer and will free it on deallocation
            return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
        }
        
        free(buffer); //free the buffer;
        return nil;
    }
    
    - (NSData *)AES256DecryptWithKey:(NSString *)key {
        // 'key' should be 32 bytes for AES256, will be null-padded otherwise
        char keyPtr[kCCKeySizeAES256+1]; // room for terminator (unused)
        bzero(keyPtr, sizeof(keyPtr)); // fill with zeroes (for padding)
        
        // fetch key data
        [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
        
        NSUInteger dataLength = [self length];
        
        //See the doc: For block ciphers, the output size will always be less than or
        //equal to the input size plus the size of one block.
        //That's why we need to add the size of one block here
        size_t bufferSize = dataLength + kCCBlockSizeAES128;
        void *buffer = malloc(bufferSize);
        
        size_t numBytesDecrypted = 0;
        CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding,
                                              keyPtr, kCCKeySizeAES256,
                                              NULL /* initialization vector (optional) */,
                                              [self bytes], dataLength, /* input */
                                              buffer, bufferSize, /* output */
                                              &numBytesDecrypted);
        
        if (cryptStatus == kCCSuccess) {
            //the returned NSData takes ownership of the buffer and will free it on deallocation
            return [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted];
        }
        
        free(buffer); //free the buffer;
        return nil;
    }
    
    @end
  • 相关阅读:
    今年暑假不AC
    Java类的生命周期
    Java反射机制
    Java环境变量的配置及使用
    javaIO流(一)
    ftp服务器测试
    linux下svn使用及查看杀掉进程
    网络配置学习
    网络配置指令
    dos攻击与防御
  • 原文地址:https://www.cnblogs.com/YouXianMing/p/3608078.html
Copyright © 2020-2023  润新知