引言
如今手機(jī)app五彩繽紛,確保手機(jī)用戶的數(shù)據(jù)安全是開發(fā)人員必須掌握的技巧,下面通過實例介紹DES在android、ios、java平臺的使用方法;
DES加密是目前最常用的對稱加密方式,性能優(yōu)于非對稱加密(RSA),是手機(jī)app請求數(shù)據(jù)加密的優(yōu)先選擇。
DES簡介:
DES全稱為Data Encryption Standard,即數(shù)據(jù)加密標(biāo)準(zhǔn),是一種使用密鑰加密的塊算法, 算法的入口參數(shù)有三個:Key、Data、Mode。
Key:為7個字節(jié)共56位,是DES算法的工作密鑰;
Data:為8個字節(jié)64位,是要被加密或被解密的數(shù)據(jù);
Mode:為DES的工作方式,有兩種:加密或解密。
3DES簡介:
3DES(或稱為Triple DES)是三重數(shù)據(jù)加密算法(TDEA,Triple Data Encryption
Algorithm)塊密碼的通稱。它相當(dāng)于是對每個數(shù)據(jù)塊應(yīng)用三次DES加密算法。由于計算機(jī)運算能力的增強(qiáng),原版DES密碼的密鑰長度變得容易被暴力破解;3DES即是設(shè)計用來提供一種相對簡單的方法,即通過增加DES的密鑰長度來避免類似的攻擊,而不是設(shè)計一種全新的塊密碼算法。因此比起最初的DES,3DES更為安全。
加密實例:
java版
packagecom.v1.linxun.portal.utils;
importjava.security.Key;
importjavax.crypto.Cipher;
importjavax.crypto.SecretKeyFactory;
importjavax.crypto.spec.DESedeKeySpec;
importjavax.crypto.spec.IvParameterSpec;
/**
* 3DES加密工具類
*/
publicclassDes3Util {
// 密鑰 長度不得小于24
privatefinalstaticStringsecretKey=?"123456789012345678901234"?;
// 向量 可有可無 終端后臺也要約定
privatefinalstaticStringiv=?"01234567";
// 加解密統(tǒng)一使用的編碼方式
privatefinalstaticStringencoding=?"utf-8";
/**
* 3DES加密
*
*@paramplainText
*??????????? 普通文本
*@return
*@throwsException
*/
publicstaticString encode(String?plainText)throwsException {
Key?deskey?=null;
DESedeKeySpec?spec?=newDESedeKeySpec(secretKey.getBytes());
SecretKeyFactory?keyfactory?= SecretKeyFactory.getInstance(?"desede");
deskey?=?keyfactory.generateSecret(?spec);
Cipher?cipher?= Cipher.getInstance(?"desede/CBC/PKCS5Padding");
IvParameterSpec?ips?=newIvParameterSpec(iv.getBytes());
cipher.init(Cipher.ENCRYPT_MODE,?deskey,?ips);
byte[]?encryptData?=?cipher.doFinal(?plainText.getBytes(encoding));
returnBase64.encode(?encryptData);
}
/**
* 3DES解密
*
*@paramencryptText
*??????????? 加密文本
*@return
*@throwsException
*/
publicstaticString decode(String?encryptText)throwsException?{
Key?deskey?=null;
DESedeKeySpec?spec?=newDESedeKeySpec(secretKey.getBytes());
SecretKeyFactory?keyfactory?= SecretKeyFactory.getInstance(?"desede");
deskey?=?keyfactory.?generateSecret(?spec);
Cipher?cipher?= Cipher.getInstance(?"desede/CBC/PKCS5Padding"?);
IvParameterSpec?ips?=newIvParameterSpec(iv.getBytes());
cipher.?init(Cipher.DECRYPT_MODE,?deskey,?ips);
byte[]?decryptData?=?cipher.?doFinal(Base64.decode(encryptText?));
returnnewString(?decryptData,encoding);
}
publicstaticvoidmain(String?args[])throwsException{
String?str?=?"你好"?;
System.out.println(?"----加密前-----:"?+?str?);
String?encodeStr?= Des3Util.encode(?str);
System.out.println(?"----加密后-----:"?+?encodeStr?);
System.out.println(?"----解密后-----:"?+ Des3Util.decode(?encodeStr));
}
}
Android版:
packagecom.inn.test;
importjava.security.Key;
importjavax.crypto.Cipher;
importjavax.crypto.SecretKeyFactory;
importjavax.crypto.spec.DESedeKeySpec;
importjavax.crypto.spec.IvParameterSpec;
importandroid.util.Base64;
/**
*?Android?3DES加密工具類
*/
publicclassAndroidDes3Util {
// 密鑰 長度不得小于24
privatefinalstaticStringsecretKey=?"123456789012345678901234"?;
// 向量 可有可無 終端后臺也要約定
privatefinalstaticStringiv=?"01234567"?;
// 加解密統(tǒng)一使用的編碼方式
privatefinalstaticStringencoding=?"utf-8"?;
/**
* 3DES加密
*
*@paramplainText
*??????????? 普通文本
*@return
*@throwsException
*/
publicstaticString encode(String plainText)throwsException {
Key deskey =null;
DESedeKeySpec spec =newDESedeKeySpec(secretKey.getBytes());
SecretKeyFactory keyfactory = SecretKeyFactory.getInstance(?"desede");
deskey = keyfactory.generateSecret(spec);
Cipher cipher = Cipher.getInstance(?"desede/CBC/PKCS5Padding");
IvParameterSpec ips =newIvParameterSpec(iv.getBytes());
cipher.init(Cipher.ENCRYPT_MODE, deskey, ips);
byte[] encryptData = cipher.doFinal(plainText.getBytes(encoding));
returnBase64.encodeToString(encryptData,Base64.DEFAULT);
}
/**
* 3DES解密
*
*@paramencryptText
*??????????? 加密文本
*@return
*@throwsException
*/
publicstaticString decode(String encryptText)throwsException {
Key deskey =null;
DESedeKeySpec spec =newDESedeKeySpec(secretKey.getBytes());
SecretKeyFactory keyfactory = SecretKeyFactory.getInstance(?"desede"?);
deskey = keyfactory.?generateSecret(spec);
Cipher cipher = Cipher.getInstance(?"desede/CBC/PKCS5Padding"?);
IvParameterSpec ips =newIvParameterSpec(iv.getBytes());
cipher.?init(Cipher.DECRYPT_MODE, deskey, ips);
byte[] decryptData = cipher.doFinal(Base64.decode(encryptText, Base64.DEFAULT));
returnnewString?(decryptData,encoding);
}
}
IOS版:
//
//? DES3EncryptUtil.h
//? DES3加解密工具
//
//? Created by xc on 15/12/18.
//? Copyright ? 2015年 xc. All rights reserved.
//
#import
@interface DES3EncryptUtil : NSObject
// 加密方法
+ (NSString*)encrypt:(NSString*)plainText;
// 解密方法
+ (NSString*)decrypt:(NSString*)encryptText;
@end
//
//? DES3EncryptUtil.m
//? DES3加解密工具
//? Created by xc on 15/12/18.
//? Copyright ? 2015年 xc. All rights reserved.
#import
#import
#import "MyBase64.h"
//秘鑰
#define gkey??????????? @"xiangchao@qq.comrnnchina"
//向量
#define gIv???????????? @"01234567"
@implementation DES3EncryptUtil : NSObject
// 加密方法
+ (NSString*)encrypt:(NSString*)plainText {
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 *) [gkey UTF8String];
const void *vinitVec = (const void *) [gIv UTF8String];
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 = [MyBase64 base64EncodedStringFrom:myData];
return result;
}
// 解密方法
+ (NSString*)decrypt:(NSString*)encryptText {
NSData *encryptData = [MyBase64 dataWithBase64EncodedString:encryptText];
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 *) [gkey 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;
}
@end
IOS加密工具中會將加密后的密文 轉(zhuǎn)化程Base64的字符串,用到了Base64編碼工具,如下
//
//? CommonFunc.h
//? PRJ_base64
//
//? Created by wangzhipeng on 12-11-29.
//? Copyright (c) 2012年 com.comsoft. All rights reserved.
//
#import
#define __BASE64( text )??????? [CommonFunc base64StringFromText:text]
#define __TEXT( base64 )??????? [CommonFunc textFromBase64String:base64]
@interface MyBase64 : NSObject
/******************************************************************************
函數(shù)名稱 : + (NSString *)base64StringFromText:(NSString *)text
函數(shù)描述 : 將文本轉(zhuǎn)換為base64格式字符串
輸入?yún)?shù) : (NSString *)text??? 文本
輸出參數(shù) : N/A
返回參數(shù) : (NSString *)??? base64格式字符串
備注信息 :
******************************************************************************/
+ (NSString *)base64StringFromText:(NSString *)text;
/******************************************************************************
函數(shù)名稱 : + (NSString *)base64StringFromText:(NSString *)text
函數(shù)描述 : 將文本轉(zhuǎn)換為base64格式字符串
輸入?yún)?shù) : (NSString *)text??? 文本
輸出參數(shù) : N/A
返回參數(shù) : (NSString *)??? base64格式字符串
備注信息 :
******************************************************************************/
+ (NSString *)base64EncodedStringFrom:(NSData *)data;
/******************************************************************************
函數(shù)名稱 : + (NSString *)textFromBase64String:(NSString *)base64
函數(shù)描述 : 將base64格式字符串轉(zhuǎn)換為文本
輸入?yún)?shù) : (NSString *)base64? base64格式字符串
輸出參數(shù) : N/A
返回參數(shù) : (NSString *)??? 文本
備注信息 :
******************************************************************************/
+ (NSString *)textFromBase64String:(NSString *)base64;
/******************************************************************************
函數(shù)名稱 : + (NSString *)textFromBase64String:(NSString *)base64
函數(shù)描述 : 將base64格式字符串轉(zhuǎn)換為文本
輸入?yún)?shù) : (NSString *)base64? base64格式字符串
輸出參數(shù) : N/A
返回參數(shù) : (NSString *)??? 文本
備注信息 :
******************************************************************************/
+ (NSData *)dataWithBase64EncodedString:(NSString *)string;
@end
//
//? CommonFunc.m
//? PRJ_base64
//
//? Created by wangzhipeng on 12-11-29.
//? Copyright (c) 2012年 com.comsoft. All rights reserved.
//
#import "MyBase64.h"
//引入IOS自帶密碼庫
#import
//空字符串
#define LocalStr_None?? @""
static const char encodingTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
@implementation MyBase64 : NSObject
+ (NSString *)base64StringFromText:(NSString *)text
{
if (text && ![text isEqualToString:LocalStr_None]) {
//取項目的bundleIdentifier作為KEY? 改動了此處
//NSString *key = [[NSBundle mainBundle] bundleIdentifier];
NSData *data = [text dataUsingEncoding:NSUTF8StringEncoding];
//IOS 自帶DES加密 Begin? 改動了此處
//data = [self DESEncrypt:data WithKey:key];
//IOS 自帶DES加密 End
return [self base64EncodedStringFrom:data];
}
else {
return LocalStr_None;
}
}
+ (NSString *)textFromBase64String:(NSString *)base64
{
if (base64 && ![base64 isEqualToString:LocalStr_None]) {
//取項目的bundleIdentifier作為KEY?? 改動了此處
//NSString *key = [[NSBundle mainBundle] bundleIdentifier];
NSData *data = [self dataWithBase64EncodedString:base64];
//IOS 自帶DES解密 Begin??? 改動了此處
//data = [self DESDecrypt:data WithKey:key];
//IOS 自帶DES加密 End
return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
}
else {
return LocalStr_None;
}
}
/******************************************************************************
函數(shù)名稱 : + (NSData *)DESEncrypt:(NSData *)data WithKey:(NSString *)key
函數(shù)描述 : 文本數(shù)據(jù)進(jìn)行DES加密
輸入?yún)?shù) : (NSData *)data
(NSString *)key
輸出參數(shù) : N/A
返回參數(shù) : (NSData *)
備注信息 : 此函數(shù)不可用于過長文本
******************************************************************************/
+ (NSData *)DESEncrypt:(NSData *)data WithKey:(NSString *)key
{
char keyPtr[kCCKeySizeAES256+1];
bzero(keyPtr, sizeof(keyPtr));
[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
NSUInteger dataLength = [data length];
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void *buffer = malloc(bufferSize);
size_t numBytesEncrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmDES,
kCCOptionPKCS7Padding | kCCOptionECBMode,
keyPtr, kCCBlockSizeDES,
NULL,
[data bytes], dataLength,
buffer, bufferSize,
&numBytesEncrypted);
if (cryptStatus == kCCSuccess) {
return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
}
free(buffer);
return nil;
}
/******************************************************************************
函數(shù)名稱 : + (NSData *)DESEncrypt:(NSData *)data WithKey:(NSString *)key
函數(shù)描述 : 文本數(shù)據(jù)進(jìn)行DES解密
輸入?yún)?shù) : (NSData *)data
(NSString *)key
輸出參數(shù) : N/A
返回參數(shù) : (NSData *)
備注信息 : 此函數(shù)不可用于過長文本
******************************************************************************/
+ (NSData *)DESDecrypt:(NSData *)data WithKey:(NSString *)key
{
char keyPtr[kCCKeySizeAES256+1];
bzero(keyPtr, sizeof(keyPtr));
[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
NSUInteger dataLength = [data length];
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void *buffer = malloc(bufferSize);
size_t numBytesDecrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmDES,
kCCOptionPKCS7Padding | kCCOptionECBMode,
keyPtr, kCCBlockSizeDES,
NULL,
[data bytes], dataLength,
buffer, bufferSize,
&numBytesDecrypted);
if (cryptStatus == kCCSuccess) {
return [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted];
}
free(buffer);
return nil;
}
/******************************************************************************
函數(shù)名稱 : + (NSData *)dataWithBase64EncodedString:(NSString *)string
函數(shù)描述 : base64格式字符串轉(zhuǎn)換為文本數(shù)據(jù)
輸入?yún)?shù) : (NSString *)string
輸出參數(shù) : N/A
返回參數(shù) : (NSData *)
備注信息 :
******************************************************************************/
+ (NSData *)dataWithBase64EncodedString:(NSString *)string
{
if (string == nil)
[NSException raise:NSInvalidArgumentException format:nil];
if ([string length] == 0)
return [NSData data];
static char *decodingTable = NULL;
if (decodingTable == NULL)
{
decodingTable = malloc(256);
if (decodingTable == NULL)
return nil;
memset(decodingTable, CHAR_MAX, 256);
NSUInteger i;
for (i = 0; i < 64; i++)
decodingTable[(short)encodingTable[i]] = i;
}
const char *characters = [string cStringUsingEncoding:NSASCIIStringEncoding];
if (characters == NULL)???? //? Not an ASCII string!
return nil;
char *bytes = malloc((([string length] + 3) / 4) * 3);
if (bytes == NULL)
return nil;
NSUInteger length = 0;
NSUInteger i = 0;
while (YES)
{
char buffer[4];
short bufferLength;
for (bufferLength = 0; bufferLength < 4; i++)
{
if (characters[i] == '\0')
break;
if (isspace(characters[i]) || characters[i] == '=')
continue;
buffer[bufferLength] = decodingTable[(short)characters[i]];
if (buffer[bufferLength++] == CHAR_MAX)????? //? Illegal character!
{
free(bytes);
return nil;
}
}
if (bufferLength == 0)
break;
if (bufferLength == 1)????? //? At least two characters are needed to produce one byte!
{
free(bytes);
return nil;
}
//? Decode the characters in the buffer to bytes.
bytes[length++] = (buffer[0] << 2) | (buffer[1] >> 4);
if (bufferLength > 2)
bytes[length++] = (buffer[1] << 4) | (buffer[2] >> 2);
if (bufferLength > 3)
bytes[length++] = (buffer[2] << 6) | buffer[3];
}
bytes = realloc(bytes, length);
return [NSData dataWithBytesNoCopy:bytes length:length];
}
/******************************************************************************
函數(shù)名稱 : + (NSString *)base64EncodedStringFrom:(NSData *)data
函數(shù)描述 : 文本數(shù)據(jù)轉(zhuǎn)換為base64格式字符串
輸入?yún)?shù) : (NSData *)data
輸出參數(shù) : N/A
返回參數(shù) : (NSString *)
備注信息 :
******************************************************************************/
+ (NSString *)base64EncodedStringFrom:(NSData *)data
{
if ([data length] == 0)
return @"";
char *characters = malloc((([data length] + 2) / 3) * 4);
if (characters == NULL)
return nil;
NSUInteger length = 0;
NSUInteger i = 0;
while (i < [data length])
{
char buffer[3] = {0,0,0};
short bufferLength = 0;
while (bufferLength < 3 && i < [data length])
buffer[bufferLength++] = ((char *)[data bytes])[i++];
//? Encode the bytes in the buffer to four characters, including padding "=" characters if necessary.
characters[length++] = encodingTable[(buffer[0] & 0xFC) >> 2];
characters[length++] = encodingTable[((buffer[0] & 0x03) << 4) | ((buffer[1] & 0xF0) >> 4)];
if (bufferLength > 1)
characters[length++] = encodingTable[((buffer[1] & 0x0F) << 2) | ((buffer[2] & 0xC0) >> 6)];
else characters[length++] = '=';
if (bufferLength > 2)
characters[length++] = encodingTable[buffer[2] & 0x3F];
else characters[length++] = '=';
}
return [[NSString alloc] initWithBytesNoCopy:characters length:length encoding:NSASCIIStringEncoding freeWhenDone:YES];
}
@end
到此為止,三平臺的加密已經(jīng)全部結(jié)束,代碼可以直接使用。
轉(zhuǎn)自:http://www.cnblogs.com/oc-bowen/p/5622914.html