【加密算法】3DES加密算法
3DES
3DES(或称为Triple DES)是三重数据加密算法(TDEA,Triple Data Encryption Algorithm)块密码的通称。它相当于是对每个数据块应用三次DES加密算法。由于计算机运算能力的增强,原版DES密码的密钥长度变得容易被暴力破解;3DES即是设计用来提供一种相对简单的方法,即通过增加DES的密钥长度来避免类似的攻击,而不是设计一种全新的块密码算法。
3DES又称Triple DES,是DES加密算法的一种模式,它使用3条56位的密钥对数据进行三次加密。数据加密标准(DES)是美国的一种由来已久的加密标准,它使用对称密钥加密法,并于1981年被ANSI组织规范为ANSI X.3.92。DES使用56位密钥和密码块的方法,而在密码块的方法中,文本被分成64位大小的文本块然后再进行加密。比起最初的DES,3DES更为安全。
3DES(即Triple DES)是DES向AES过渡的加密算法(1999年,NIST将3-DES指定为过渡的加密标准),是DES的一个更安全的变形。它以DES为基本模块,通过组合分组方法设计出分组加密算法,其具体实现如下:设Ek()和Dk()代表DES算法的加密和解密过程,K代表DES算法使用的密钥,P代表明文,C代表密文,这样:
3DES加密过程为:C=Ek3(Dk2(Ek1(P)))
3DES解密过程为:P=Dk1(EK2(Dk3(C)))
历史发展
3DES(即Triple DES)是DES向AES过渡的加密算法,它使用3条56位的密钥对数据进行三次加密。是DES的一个更安全的变形。它以DES为基本模块,通过组合分组方法设计出分组加密算法。比起最初的DES,3DES更为安全。
3DES算法
3DES算法是指使用双长度(16字节)密钥K=(KL||KR)将8字节明文数据块进行3次DES加密/解密。如下所示:
Y = DES( KL[DES-1( KR[DES( KL[X] )] )] )
解密方式为:
X = DES-1( KL[DES( KR[DES-1( KL[Y] )] )] )
其中,DES( KL[X] )表示用密钥K对数据X进行DES加密,DES-1( KL[Y] )表示用密钥K对数据Y进行解密。
Android、iPhone和Java三个平台一致的加密算法
手机端后台通常是用JAVA开发的Web Service,Android和iPhone客户端调用同样的Web Service接口,为了数据安全考虑,要对数据进行加密。头疼的问题就来了,很难编写出一套加密程序,在3个平台间加解密的结果一致,然而一套3DES加密程序,能够实现Java、Android和iPhone三个平台加解密一 致。
iPhone端的加密程序,OC写的3DES加密程序,源代码如下:
#import <Foundation/Foundation.h>
@interface DES3Util : NSObject// 加密方法
+ (NSString*)encrypt:(NSString*)plainText; // 解密方法
+ (NSString*)decrypt:(NSString*)encryptText;
@end
//下面的GTMBase64为第三方类,可去git下载,这里代码就不给了
#import "DES3Util.h"
#import <CommonCrypto/CommonCryptor.h>
#import "GTMBase64.h" #define gkey @"liuyunqiang@lx100$#365#$"
#define gIv @"01234567" @implementation DES3Util // 加密方法
+ (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 = [GTMBase64 stringByEncodingData:myData]; return result;
}
// 解密方法
+ (NSString*)decrypt:(NSString*)encryptText { NSData *encryptData = [GTMBase64 decodeData:[encryptText 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 *) [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] autorelease]; return result;
} @end
2).Java端的加密工具类,适用于Android端,无需任何修改,即可保证Java与Android端的加密一致,并且中文不会乱码。
package org.liuyq.des3; import java.security.Key; import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import javax.crypto.spec.IvParameterSpec; /** * 3DES加密工具类 * * @author liufeng * @date 2012-10-11 */
public class Des3 { // 密钥 private final static String secretKey = "liuyunqiang@lx100$#365#$" ; // 向量 private final static String iv = "01234567" ; // 加解密统一使用的编码方式 private final static String encoding = "utf-8" ; /** * 3DES加密 * * @param plainText 普通文本 * @return * @throws Exception */ public static String encode(String plainText) throws Exception { Key deskey = null ; DESedeKeySpec spec = new DESedeKeySpec(secretKey.getBytes()); SecretKeyFactory keyfactory = SecretKeyFactory.getInstance( "desede" ); 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 Base64.encode(encryptData); } /** * 3DES解密 * * @param encryptText 加密文本 * @return * @throws Exception */ public static String decode(String encryptText) throws Exception { Key deskey = null ; DESedeKeySpec spec = new DESedeKeySpec(secretKey.getBytes()); SecretKeyFactory keyfactory = SecretKeyFactory.getInstance( "desede" ); deskey = keyfactory.generateSecret(spec); Cipher cipher = Cipher.getInstance( "desede/CBC/PKCS5Padding" ); IvParameterSpec ips = new IvParameterSpec(iv.getBytes()); cipher.init(Cipher.DECRYPT_MODE, deskey, ips); byte [] decryptData = cipher.doFinal(Base64.decode(encryptText)); return new String(decryptData, encoding); }
}
上面的加密工具类会使用到Base64这个类,该类的源代码如下:
package org.liuyq.des3;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream; /** * Base64编码工具类 * * @author liufeng * @date 2012-10-11 */
public class Base64 { private static final char [] legalChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" .toCharArray(); public static String encode( byte [] data) { int start = 0 ; int len = data.length; StringBuffer buf = new StringBuffer(data.length * 3 / 2 ); int end = len - 3 ; int i = start; int n = 0 ; while (i <= end) { int d = (((( int ) data[i]) & 0x0ff ) << 16 ) | (((( int ) data[i + 1 ]) & 0x0ff ) << 8 ) | ((( int ) data[i + 2 ]) & 0x0ff ); buf.append(legalChars[(d >> 18 ) & 63 ]); buf.append(legalChars[(d >> 12 ) & 63 ]); buf.append(legalChars[(d >> 6 ) & 63 ]); buf.append(legalChars[d & 63 ]); i += 3 ; if (n++ >= 14 ) { n = 0 ; buf.append( " " ); } } if (i == start + len - 2 ) { int d = (((( int ) data[i]) & 0x0ff ) << 16 ) | (((( int ) data[i + 1 ]) & 255 ) << 8 ); buf.append(legalChars[(d >> 18 ) & 63 ]); buf.append(legalChars[(d >> 12 ) & 63 ]); buf.append(legalChars[(d >> 6 ) & 63 ]); buf.append( "=" ); } else if (i == start + len - 1 ) { int d = ((( int ) data[i]) & 0x0ff ) << 16 ; buf.append(legalChars[(d >> 18 ) & 63 ]); buf.append(legalChars[(d >> 12 ) & 63 ]); buf.append( "==" ); } return buf.toString(); } private static int decode( char c) { if (c >= 'A' && c <= 'Z' ) return (( int ) c) - 65 ; else if (c >= 'a' && c <= 'z' ) return (( int ) c) - 97 + 26 ; else if (c >= '0' && c <= '9' ) return (( int ) c) - 48 + 26 + 26 ; else switch (c) { case '+' : return 62 ; case '/' : return 63 ; case '=' : return 0 ; default : throw new RuntimeException( "unexpected code: " + c); } } /** * Decodes the given Base64 encoded String to a new byte array. The byte array holding the decoded data is returned. */ public static byte [] decode(String s) { ByteArrayOutputStream bos = new ByteArrayOutputStream(); try { decode(s, bos); } catch (IOException e) { throw new RuntimeException(); } byte [] decodedBytes = bos.toByteArray(); try { bos.close(); bos = null ; } catch (IOException ex) { System.err.println( "Error while decoding BASE64: " + ex.toString()); } return decodedBytes; } private static void decode(String s, OutputStream os) throws IOException { int i = 0 ; int len = s.length(); while ( true ) { while (i < len && s.charAt(i) <= ' ' ) i++; if (i == len) break ; int tri = (decode(s.charAt(i)) << 18 ) + (decode(s.charAt(i + 1 )) << 12 ) + (decode(s.charAt(i + 2 )) << 6 ) + (decode(s.charAt(i + 3 ))); os.write((tri >> 16 ) & 255 ); if (s.charAt(i + 2 ) == '=' ) break ; os.write((tri >> 8 ) & 255 ); if (s.charAt(i + 3 ) == '=' ) break ; os.write(tri & 255 ); i += 4 ; } }
}
参考链接:http://developer.51cto.com/art/201311/419158_all.htm
http://www.seacha.com/tools/3des.html?src=1234567890&mode=CBC&keylen=128&key=uban1231&iv=01234567&bpkcs=pkcs7padding&session=s9eDBpeLxJA6m2k1mugh&des=8ea2d7a28b5196c29aee78a824429aa4&encoding=base64&type=0
【加密算法】3DES加密算法相关推荐
- 安全架构-加密算法-3DES加密算法.NET C#实现
C# 3Des加密解密 C#使用填充模式"PaddingMode.PKCS7和CipherMode.CBC",可按需修改,使用CBC模式的话在C#下必须传入加密向量IV(固定长度8 ...
- TripleDES类 3des加密算法实现
可以加密字符串,也可以加密字节数组. 采用3-des加密算法,加密键只能是16byte(128位)或者是24byte(192位)的,指定的键不仅有长度上的要求,还不能是个弱键 ( 注:DES 算法使 ...
- 3DES加密算法原理及实现过程
之前介绍了DES算法的原理和实现过程,现在介绍一下3DES的原理和实现过程. DES算法的密钥长度为64位(实际有效长度为56位,因为每隔8位中有1位为校验位,使用的是奇偶校验法). 其实3DES就是 ...
- DES和3DES加密算法C语言实现
DES和3DES加密算法C语言实现 记录DES和3DES加密算法最简洁易懂的C语言源码 主要是要用到CBC这部分的算法,后边也有一个工具可以提供验证,因为网上的工具含有CBC的很少,也方便大家吧 之前 ...
- DES、3DES加密算法
DES加密算法,为对称加密算法中的一种.70年代初由IBM研发,后1977年被美国国家标准局采纳为数据加密标准,即DES全称的由来:Data Encryption Standard.对称加密算法,是相 ...
- 简述3DES加密算法
之前我们聊了DES加密算法,在文章的最后我们提到了人们为了克服DES加密算法的不足,提出了三重DES,也就是3DES,今天我们就来简单了解一下它. 什么是3DES? 3DES,也称为3DESede或T ...
- VB.NET学习笔记(一):MD5、SHA256、3DES加密算法
测试环境:windows10和Microsoft Visual Studio 2010 文章要点: 1.System.Security.Cryptography介绍 2.加密算法介绍 3.使用加密服务 ...
- 3DES加密算法原理及实现
目录 引语 加密 加密算法公式 为什么采用加密-解密-加密的形式 解密 代码实现 注意:3DES是3重DES加解密算法,具体原理同DES,不在赘述. 引语 DES算法是全网公开的,其安全性是依靠秘钥的 ...
- aes加密算法python语言实现_python实现AES/DES/RSA/MD5/SM2/SM4/3DES加密算法模板汇总
都是作者累积的,且看其珍惜,大家可以尽量可以保存一下,如果转载请写好出处https://www.cnblogs.com/pythonywy 一.md5加密 1.简介 这是一种使用非常广泛的加密方式,不 ...
- 安全架构-加密算法-3DES加密java实现
3DES加密java实现 3DES是三重数据加密,且可以逆推的一种算法方案.但由于3DES的算法是公开的,所以算法本身没有秘密,主要依靠唯一密钥来确保数据加解密的安全.到目前为止,仍没有人能破解3DE ...
最新文章
- [Vue] : 键盘修饰符
- 用 Python 将微信热文转换成Word文档 | 神级操作
- iphone 各种例子 汇总
- UE4 HTC VIVE 多人联机
- 【计算机就业-算法工程师】校招想去互联网公司担任算法工程师该怎么准备
- Dubbo3.0 简介
- python 嵌入键值数据库_键值对数据库综述
- 关于MPU6050学习的一些总结之一MPU6050芯片手册的整理
- 软工专硕考研_你可能需要了解--2018年北京大学软微软件工程专硕考研 经验分享...
- python 等腰三角形的性质,相似三角形性质判定().ppt
- 【航天物流组参赛ReadMe.md】
- 前端培训教程JavaScript
- 当前不会命中断点还未为文档加载任何符号——问题探究
- 简单对应分析案例《好评数据分析》
- Vue-Element-admin 框架上使用 Hiprint 打印插件 一、项目介绍
- 相机光学(十五)——如何提高相机标定的精度
- Linux命令——修改root密码
- Mysql flush privileges
- Vue 仿淘宝购物车
- 电信IPTV直播源抓取