今天对3DES的加密方式做了一次深入的了解,因为近期的项目需要,要对接口进行加密处理,所以经大家一致讨论,采取了DES的加密方式,但是这其中也出现了一些问题,浪费了一些时间,在这里,笔者将自己DES加密的方法分享给大家,希望能帮助大家~~
1.首先进行DSE加密必须要有Base64文件,这里笔者就不过多的去介绍Base64,因为Base64都是一样的,只要将下载好的Base64集成到工程中就好
2.这里定义一个des的文件为MGDes
3.在.h文件中要声明加密和解密的方法:
/**
* 对传入的所有请求参数进行DES3加密
*/
+ (NSString *)encryptParameters:(NSString *)string;
/**
* 对传入的所有请求参数进行DES3解密
*/
+ (NSString *)decryptUseDES:(NSString *)cipherText key:(NSString *)key;
4.在.m文件实现类方法
(1)首先定义个加密的私钥
#define DES_KEY @"24位(一定要24位)"
(2)导入头文件
#import "GTMBase64.h"
#import <CommonCrypto/CommonCryptor.h>
#import <CommonCrypto/CommonHMAC.h>
#import <CommonCrypto/CommonDigest.h>
(3)定义偏移量
#define gIv @"01234567"
(4)实现+方法
//加密方法
+ (NSString *)encryptParameters:(NSString *)string
{
return [self encryptUseDES:string key:DES_KEY];
}
+ (NSString *) encryptUseDES:(NSString *)plainText key:(NSString *)key
{
NSData* data = [plainText dataUsingEncoding:NSUTF8StringEncoding];
size_t plainTextBufferSize = [data length];
const void *vplainText = (const void *)[data bytes];
CCCryptorStatus ccStatus;
uint8_t *bufferPtr = NULL;
size_t bufferPtrSize = 0;
size_t movedBytes = 0;
bufferPtrSize = (plainTextBufferSize + kCCBlockSize3DES) & ~(kCCBlockSize3DES - 1);
bufferPtr = malloc( bufferPtrSize * sizeof(uint8_t));
memset((void *)bufferPtr, 0x0, bufferPtrSize);
const void *vkey = (const void *) [key UTF8String];
const void *vinitVec = (const void *) [gIv UTF8String];
//kCCOptionPKCS7Padding
ccStatus = CCCrypt(kCCEncrypt,
kCCAlgorithm3DES,
kCCOptionPKCS7Padding,
vkey,
kCCKeySize3DES,
vinitVec,
vplainText,
plainTextBufferSize,
(void *)bufferPtr,
bufferPtrSize,
&movedBytes);
NSData *myData = [NSData dataWithBytes:(const void *)bufferPtr length:(NSUInteger)movedBytes];
NSString *result = [GTMBase64 stringByEncodingData:myData];
return result;
}
//解密方法
+ (NSString *)decryptUseDES:(NSString *)cipherText key:(NSString *)key
{
NSData *encryptData = [GTMBase64 decodeData:[cipherText dataUsingEncoding:NSUTF8StringEncoding]];
size_t plainTextBufferSize = [encryptData length];
const void *vplainText = [encryptData bytes];
CCCryptorStatus ccStatus;
uint8_t *bufferPtr = NULL;
size_t bufferPtrSize = 0;
size_t movedBytes = 0;
bufferPtrSize = (plainTextBufferSize + kCCBlockSize3DES) & ~(kCCBlockSize3DES - 1);
bufferPtr = malloc( bufferPtrSize * sizeof(uint8_t));
memset((void *)bufferPtr, 0x0, bufferPtrSize);
const void *vkey = (const void *) [key UTF8String];
const void *vinitVec = (const void *) [gIv UTF8String];
ccStatus = CCCrypt(kCCDecrypt,
kCCAlgorithm3DES,
kCCOptionPKCS7Padding,
vkey,
kCCKeySize3DES,
vinitVec,
vplainText,
plainTextBufferSize,
(void *)bufferPtr,
bufferPtrSize,
&movedBytes);
NSString *result = [[NSString alloc] initWithData:[NSData dataWithBytes:(const void *)bufferPtr length:(NSUInteger)movedBytes] encoding:NSUTF8StringEncoding];
return result;
}
5.一定要注意,加密的私钥一定要24位,要不然会和后台和安卓加密的结果不一致,从而导致后台不能解密我们加密过的内容
6.附上一段安卓的代码,安卓和iOS和后台一定要一致。
//加密方法(安卓)
public static String encode(String plainText, String key) throws Exception { DESedeKeySpec spec = new DESedeKeySpec(getKey(key).getBytes()); SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede"); Key deskey = keyfactory.generateSecret(spec); Cipher cipher = Cipher.getInstance("desede/CBC/PKCS5Padding"); IvParameterSpec ips = new IvParameterSpec(iv.getBytes()); cipher.init(Cipher.ENCRYPT_MODE, deskey, ips); byte[] encryptData = cipher.doFinal(plainText.getBytes(encoding)); return new String(Base64.encode(encryptData)); }