iOS DES ECB模式对称加密解密

先了解下 DES ECB模式

ECB模式:
优点:
1. 简单;
2. 有利于并行计算;
3. 误差不会被传递;
缺点:
1. 不能隐藏明文的模式;
2. 可能对明文进行主动攻击;

DES ECB(电子密本方式)其实非常简单,就是将数据按照8个字节一段进行DES加密或解密得到一段段的8个字节的密文或者明文,最后一段不足8个字节(一般补0或者F),按照需求补足8个字节进行计算(并行计算),之后按照顺序将计算所得的数据连在一起即可,各段数据之间互不影响。

CBC模式:
优点:
1. 不容易主动攻击,安全性好于ECB,是SSL、IPSec的标准;
缺点:
1. 不利于并行计算;
2. 误差传递;
3. 需要初始化向量IV;

DES CBC(密文分组链接方式)有点麻烦,它的实现机制使加密的各段数据之间有了联系。其实现的机理如下:
加密步骤如下:
1. 首先将数据按照8个字节一组进行分组得到D1D2......Dn(若数据不是8的整数倍,用指定的PADDING数据补位)
2. 第一组数据D1与初始化向量I异或后的结果进行DES加密得到第一组密文C1(初始化向量I为全零)
3. 第二组数据D2与第一组的加密结果C1异或以后的结果进行DES加密,得到第二组密文C2
4. 之后的数据以此类推,得到Cn
5. 按顺序连为C1C2C3......Cn即为加密结果。

首先贴出加密类的头文件:

#import <Foundation/Foundation.h>
#import <CommonCrypto/CommonCryptor.h>
#import "ConverUtil.h"
#import "Constants.h"

@interface DES : NSObject
//加密
- (NSString *) encryptUseDES:(NSString *)plainText key:(NSString*)key;
//解密
-(NSString*) decryptUseDES:(NSString*)cipherText key:(NSString*)key;

@end

加密类的实现类:

#import "DES.h"

@implementation DES
//DES_IV 自己定义的一个字符串 八个字节 一定要是八个字节
-(Byte *) getIv{
    
    NSString *testString = DES_IV;
    NSData *testData = [testString dataUsingEncoding: NSUTF8StringEncoding];
    //    for(int i=0;i<[testData length];i++)
    //        printf("testByte = %d\n",testByte[i]);
    return (Byte *)[testData bytes];
}
//plainText需加密 字符串 key 定义好的 加密 解密 钥匙
- (NSString *) encryptUseDES:(NSString *)plainText key:(NSString*)key{
    
    Byte *iv=[self getIv];
    
//    NSString *escape=[plainText stringByReplacingOccurrencesOfString:@"\"" withString:@"\\\""];
//    return escape;
    
    NSData* data=[plainText dataUsingEncoding: NSUTF8StringEncoding];
    
    NSUInteger bufferSize=([data length] + kCCKeySizeDES) & ~(kCCKeySizeDES -1);
    
    char buffer[bufferSize];
    
    memset(buffer, 0,sizeof(buffer));
    
    size_t bufferNumBytes;
    
    CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,
                                          
                                          kCCAlgorithmDES,
                                          
                                          kCCOptionPKCS7Padding,
                                          
                                          [key UTF8String],
                                          
                                          kCCKeySizeDES,
                                          
                                          iv   ,
                                          
                                          [data bytes],
                                          
                                          [data length],
                                          
                                          buffer,
                                          
                                          bufferSize,
                                          
                                          &bufferNumBytes);
    
    if (cryptStatus ==kCCSuccess) {
        
        NSData *data = [NSData dataWithBytes:buffer length:(NSUInteger)bufferNumBytes];
        
        return [ConverUtil parseByteArray2HexString:[data bytes] count:bufferNumBytes] ;
        //        NSLog(@"objccipherTextBytes:%@",[XYDES dataToHex:data]);
        //        ciphertext = [GTMBase64 stringByEncodingData:data];
        //        NSLog(@"objccipherTextBase64:%@",ciphertext);
    }
    
    return nil;
}

-(NSString*) decryptUseDES:(NSString*)cipherText key:(NSString*)key{
    
    Byte *iv=[self getIv];
    
    NSData* data = [ConverUtil parseHexToByteArray:cipherText];
    
    NSUInteger bufferSize=([data length] + kCCKeySizeDES) & ~(kCCKeySizeDES -1);
    
    char buffer[bufferSize];
    
    memset(buffer, 0,sizeof(buffer));
    
    size_t bufferNumBytes;
    
    CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt,
                                          
                                          kCCAlgorithmDES,
                                          
                                          kCCOptionPKCS7Padding,
                                          
                                          [key UTF8String],
                                          
                                          kCCKeySizeDES,
                                          
                                          iv,
                                          
                                          [data bytes],
                                          
                                          [data length],
                                          
                                          buffer,
                                          
                                          bufferSize,
                                          
                                          &bufferNumBytes);
    
    NSString* plainText = nil;
    
    if (cryptStatus ==kCCSuccess) {
        
        NSData *plainData =[NSData dataWithBytes:buffer length:(NSUInteger)bufferNumBytes];
        
        plainText = [[NSString alloc] initWithData:plainData encoding:NSUTF8StringEncoding];
    }
    
    return plainText;
}

@end

下面是转码类,主要是16进制和字节的转化 
头文件:
#import <Foundation/Foundation.h>

@interface ConverUtil : NSObject

/**
 64编码
 */
+(NSString *)base64Encoding:(NSData*) text;

/**
 字节转化为16进制数
 */
+(NSString *) parseByte2HexString:(Byte *) bytes;

/**
 字节数组转化16进制数
 */
+(NSString *) parseByteArray2HexString:(Byte[]) bytes count:(int)count;

/*
 将16进制数据转化成NSData 数组
 */
+(NSData*) parseHexToByteArray:(NSString*) hexString;

@end

实现类:

#import "ConverUtil.h"

@implementation ConverUtil
static const char encodingTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

/**
 64编码
 */
+(NSString *)base64Encoding:(NSData*) text
{
    if (text.length == 0)
        return @"";
    
    char *characters = malloc(text.length*3/2);
    
    if (characters == NULL)
        return @"";
    
    int end = text.length - 3;
    int index = 0;
    int charCount = 0;
    int n = 0;
    
    while (index <= end) {
        int d = (((int)(((char *)[text bytes])[index]) & 0x0ff) << 16)
        | (((int)(((char *)[text bytes])[index + 1]) & 0x0ff) << 8)
        | ((int)(((char *)[text bytes])[index + 2]) & 0x0ff);
        
        characters[charCount++] = encodingTable[(d >> 18) & 63];
        characters[charCount++] = encodingTable[(d >> 12) & 63];
        characters[charCount++] = encodingTable[(d >> 6) & 63];
        characters[charCount++] = encodingTable[d & 63];
        
        index += 3;
        
        if(n++ >= 14)
        {
            n = 0;
            characters[charCount++] = ' ';
        }
    }
    
    if(index == text.length - 2)
    {
        int d = (((int)(((char *)[text bytes])[index]) & 0x0ff) << 16)
        | (((int)(((char *)[text bytes])[index + 1]) & 255) << 8);
        characters[charCount++] = encodingTable[(d >> 18) & 63];
        characters[charCount++] = encodingTable[(d >> 12) & 63];
        characters[charCount++] = encodingTable[(d >> 6) & 63];
        characters[charCount++] = '=';
    }
    else if(index == text.length - 1)
    {
        int d = ((int)(((char *)[text bytes])[index]) & 0x0ff) << 16;
        characters[charCount++] = encodingTable[(d >> 18) & 63];
        characters[charCount++] = encodingTable[(d >> 12) & 63];
        characters[charCount++] = '=';
        characters[charCount++] = '=';
    }
    NSString * rtnStr = [[NSString alloc] initWithBytesNoCopy:characters length:charCount encoding:NSUTF8StringEncoding freeWhenDone:YES];
    return rtnStr;
}

/**
 字节转化为16进制数
 */
+(NSString *) parseByte2HexString:(Byte *) bytes
{
    NSMutableString *hexStr = [[NSMutableString alloc]init];
    int i = 0;
    if(bytes)
    {
        while (bytes[i] != '\0')
        {
            NSString *hexByte = [NSString stringWithFormat:@"%x",bytes[i] & 0xff];///16进制数
            if([hexByte length]==1)
                [hexStr appendFormat:@"0%@", hexByte];
            else
                [hexStr appendFormat:@"%@", hexByte];
            
            i++;
        }
    }
    
    return hexStr;
}


/**
 字节数组转化16进制数
 */
+(NSString *) parseByteArray2HexString:(Byte[]) bytes count:(int)count
{
    NSMutableString *hexStr = [[NSMutableString alloc]init];
    //    int i = 0;
    if(bytes)
    {
        //        while (bytes[i] != '\0')
        //        {
        //            NSString *hexByte = [NSString stringWithFormat:@"%x",bytes[i] & 0xff];///16进制数
        //
        
        //
        //            if([hexByte length]==1)
        //                [hexStr appendFormat:@"0%@", hexByte];
        //            else
        //                [hexStr appendFormat:@"%@", hexByte];
        //
        //            i++;
        //        }
        for (int i=0;i< count;i++)
        {
            NSString *hexByte = [NSString stringWithFormat:@"%x",bytes[i] & 0xff];///16进制数
            
            if([hexByte length]==1)
                [hexStr appendFormat:@"0%@", hexByte];
            else
                [hexStr appendFormat:@"%@", hexByte];
            
            //            i++;
        }
    }
    
    return [hexStr uppercaseString];
}

/*
 将16进制数据转化成NSData 数组
 */
+(NSData*) parseHexToByteArray:(NSString*) hexString
{
    int j=0;
    Byte bytes[hexString.length];
    for(int i=0;i<[hexString length];i++)
    {
        int int_ch;  /// 两位16进制数转化后的10进制数
        unichar hex_char1 = [hexString characterAtIndex:i]; 两位16进制数中的第一位(高位*16)
        int int_ch1;
        if(hex_char1 >= '0' && hex_char1 <='9')
            int_ch1 = (hex_char1-48)*16;    0 的Ascll - 48
        else if(hex_char1 >= 'A' && hex_char1 <='F')
            int_ch1 = (hex_char1-55)*16;  A 的Ascll - 65
        else
            int_ch1 = (hex_char1-87)*16;  a 的Ascll - 97
        i++;
        unichar hex_char2 = [hexString characterAtIndex:i]; ///两位16进制数中的第二位(低位)
        int int_ch2;
        if(hex_char2 >= '0' && hex_char2 <='9')
            int_ch2 = (hex_char2-48);  0 的Ascll - 48
        else if(hex_char2 >= 'A' && hex_char1 <='F')
            int_ch2 = hex_char2-55;  A 的Ascll - 65
        else
            int_ch2 = hex_char2-87;  a 的Ascll - 97
        
        int_ch = int_ch1+int_ch2;
        bytes[j] = int_ch;  ///将转化后的数放入Byte数组里
        j++;
    }
    
    NSData *newData = [[NSData alloc] initWithBytes:bytes length:hexString.length/2];
    
    return newData;
}

@end



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
iOS中使用OpenSSL实现AES-GCM和ECB加密解密需要以下步骤: 1. 下载OpenSSL库并将其添加到iOS项目中。 2. 导入OpenSSL库头文件: ```objc #import <openssl/evp.h> #import <openssl/aes.h> ``` 3. 实现AES-GCM加密解密: ```objc // AES-GCM加密 + (NSData *)AESGCMEncryptWithKey:(NSData *)key iv:(NSData *)iv aad:(NSData *)aad plainText:(NSData *)plainText tagLength:(NSUInteger)tagLength { EVP_CIPHER_CTX *ctx; int len, outlen; unsigned char *outbuf; NSData *tag = nil; NSData *cipherText = nil; // 初始化EVP_CIPHER_CTX ctx = EVP_CIPHER_CTX_new(); EVP_EncryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL); // 设置key和iv EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, (int)iv.length, NULL); EVP_EncryptInit_ex(ctx, NULL, NULL, key.bytes, iv.bytes); // 设置aad EVP_EncryptUpdate(ctx, NULL, &len, aad.bytes, (int)aad.length); // 加密明文 outbuf = malloc(plainText.length + AES_BLOCK_SIZE); EVP_EncryptUpdate(ctx, outbuf, &len, plainText.bytes, (int)plainText.length); cipherText = [NSData dataWithBytes:outbuf length:len]; free(outbuf); // 获取tag outbuf = malloc(tagLength); EVP_EncryptFinal_ex(ctx, outbuf, &outlen); tag = [NSData dataWithBytes:outbuf length:outlen]; free(outbuf); // 释放EVP_CIPHER_CTX EVP_CIPHER_CTX_free(ctx); // 返回加密结果和tag NSMutableData *resultData = [NSMutableData dataWithData:cipherText]; [resultData appendData:tag]; return resultData; } // AES-GCM解密 + (NSData *)AESGCMDecryptWithKey:(NSData *)key iv:(NSData *)iv aad:(NSData *)aad cipherText:(NSData *)cipherText tagLength:(NSUInteger)tagLength { EVP_CIPHER_CTX *ctx; int len, outlen; unsigned char *outbuf; NSData *tag = nil; NSData *plainText = nil; // 初始化EVP_CIPHER_CTX ctx = EVP_CIPHER_CTX_new(); EVP_DecryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL); // 设置key和iv EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, (int)iv.length, NULL); EVP_DecryptInit_ex(ctx, NULL, NULL, key.bytes, iv.bytes); // 设置aad EVP_DecryptUpdate(ctx, NULL, &len, aad.bytes, (int)aad.length); // 解密密文 outbuf = malloc(cipherText.length); EVP_DecryptUpdate(ctx, outbuf, &len, cipherText.bytes, (int)cipherText.length - tagLength); plainText = [NSData dataWithBytes:outbuf length:len]; free(outbuf); // 获取tag tag = [cipherText subdataWithRange:NSMakeRange(cipherText.length - tagLength, tagLength)]; EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, (int)tag.length, (void *)tag.bytes); // 验证tag if (EVP_DecryptFinal_ex(ctx, NULL, &outlen) <= 0) { return nil; // tag验证失败 } // 释放EVP_CIPHER_CTX EVP_CIPHER_CTX_free(ctx); // 返回解密结果 return plainText; } ``` 4. 实现ECB加密解密: ```objc // ECB加密 + (NSData *)ECBEncryptWithKey:(NSData *)key plainText:(NSData *)plainText { EVP_CIPHER_CTX *ctx; int len; unsigned char *outbuf; NSData *cipherText = nil; // 初始化EVP_CIPHER_CTX ctx = EVP_CIPHER_CTX_new(); EVP_EncryptInit_ex(ctx, EVP_aes_256_ecb(), NULL, key.bytes, NULL); // 加密明文 outbuf = malloc(plainText.length + AES_BLOCK_SIZE); EVP_EncryptUpdate(ctx, outbuf, &len, plainText.bytes, (int)plainText.length); cipherText = [NSData dataWithBytes:outbuf length:len]; free(outbuf); // 释放EVP_CIPHER_CTX EVP_CIPHER_CTX_free(ctx); // 返回加密结果 return cipherText; } // ECB解密 + (NSData *)ECBDecryptWithKey:(NSData *)key cipherText:(NSData *)cipherText { EVP_CIPHER_CTX *ctx; int len; unsigned char *outbuf; NSData *plainText = nil; // 初始化EVP_CIPHER_CTX ctx = EVP_CIPHER_CTX_new(); EVP_DecryptInit_ex(ctx, EVP_aes_256_ecb(), NULL, key.bytes, NULL); // 解密密文 outbuf = malloc(cipherText.length); EVP_DecryptUpdate(ctx, outbuf, &len, cipherText.bytes, (int)cipherText.length); plainText = [NSData dataWithBytes:outbuf length:len]; free(outbuf); // 释放EVP_CIPHER_CTX EVP_CIPHER_CTX_free(ctx); // 返回解密结果 return plainText; } ``` 以上就是使用OpenSSL实现AES-GCM和ECB加密解密的步骤,需要注意的是,在iOS13及以上版本中,Apple已经将OpenSSL库废弃,推荐使用自带的CryptoKit框架实现加密解密
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值