3DES(TripleDES)实现跨平台统一加密
一、3DES简介
3DES(或称为Triple DES)是三重数据加密算法(TDEA,Triple Data Encryption Algorithm)块密码的通称。它相当于是使用3条56位的密钥对每个数据块应用三次DES加密算法。由于计算机运算能力的增强,原版DES密码的密钥长度变得容易被暴力破解;3DES即是设计用来提供一种相对简单的方法,即通过增加DES的密钥长度来避免类似的攻击,而不是设计一种全新的块密码算法。
加密算法,具体实现如下:
设Ek()和Dk()代表DES算法的加密和解密过程,K代表DES算法使用的密钥,M代表明文,C代表密文,这样:
3DES加密过程为:C=Ek3(Dk2(Ek1(M)))
3DES解密过程为:M=Dk1(EK2(Dk3(C)))
二、3DES实现跨平台加密
手机端后台通常是用JAVA开发的Web Service,而Android和IOS客户端需要调用同样的Web Service接口,为了数据安全考虑,要对数据进行加密。那么问题来了:如何编写出一套加密程序,以保证3个平台间加解密的结果一致呢?
1.相关类简介
(1)Cipher类
Cipher类为加密和解密提供密码功能。为创建 Cipher 对象,应用程序调用 Cipher 的getInstance方法并将所请求转换的名称传递给它。还可以指定提供者的名称(可选)。
[转换]是一个字符串,它描述为产生某种输出而在给定的输入上执行的操作(或一组操作)。转换始终包括加密算法的名称(例如,DES),后面可能跟有一个反馈模式和填充方案。
常用形式:“算法/模式/填充”或“算法”。
API中返回实现指定转换的 Cipher 对象:
static Cipher getInstance(String transformation) static Cipher getInstance(String transformation, Provider provider) static Cipher getInstance(String transformation, String provider)
(2)DESedeKeySpec类
DESedeKeySpec类指定一个 DES-EDE ("triple-DES") 密钥。两个构造方法:
DESedeKeySpec(byte[] key) //创建一个 DESedeKeySpec 对象,使用 key 中的前 24 个字节作为 DES-EDE 密钥的密钥内容。 DESedeKeySpec(byte[] key, int offset) //创建一个 DESedeKeySpec 对象,使用 key 中始于且包含 offset 的前 24 个字节作为 DES-EDE 密钥的密钥内容。(3)SecretKey接口
秘密(对称)密钥。此接口不包含方法或常量。其唯一目的是分组秘密密钥(并为其提供类型安全)。此接口的提供者实现必须改写继承自 java.lang.Object 的 equals 和 hashCode 方法,以便根据底层密钥材料而不是根据引用进行秘密密钥比较。
(4)SecretKeyFactory类
SecretKeyFactory类表示密钥的工厂。密钥工厂用来将密钥(类型 Key 的不透明加密密钥)转换为密钥规范(底层密钥材料的透明表示形式),反之亦然。秘密密钥工厂只对秘密(对称)密钥进行操作。密钥工厂为双工模式,即其允许根据给定密钥规范(密钥材料)构建不透明密钥对象,或以适当格式获取密钥对象的底层密钥材料。
API常用方法:
static SecretKeyFactory getInstance(String algorithm) //返回转换指定算法的秘密密钥的 SecretKeyFactory 对象。 SecretKey generateSecret(KeySpec keySpec) //根据提供的密钥规范(密钥材料)生成 SecretKey 对象。(5)IvParameterSpec类
IvParameterSpec类指定一个初始化向量 (IV)。
API构造方法:
IvParameterSpec(byte[] iv) // 使用 iv 中的字节作为 IV 来构造一个 IvParameterSpec 对象。 IvParameterSpec(byte[] iv, int offset, int len) //使用 iv 中始于且包含 offset 的前 len 个字节作为 IV 来构造一个 IvParameterSpec 对象。
2.所需参数简介
(1)算法:采用“DESede/CBC/PKCS5Padding”。
[1]DESede即3DES加密算法。
[2]CBC密码分组链接模式。这种模式是先将明文切分成若干小段,然后每一小段与初始块或者上一段的密文段进行异或运算后,再与密钥进行加密。是AES五种加密模式{CBC、ECB(电码本模式)、CTR(计算器模式)、OCF(密码反馈模式)、CFB(输出反馈模式)}之一。其它各种模式的简单原理,可参照http://www.tuicool.com/articles/AZZjiu
[3]PKCS5Padding,简单理解,就是将原文填充到符合一定加密规则的指定长度。
(2)IV初始向量:long(createTime)转成字节,long字节序采用BIG_ENDIAN;
CBC模式的作法是对第一块明文投入随机的初始向量(IV),然后将明文与向量运算的结果加密,加密的结果再作为下一块明文的向量。这种做法的最终目的是要达到语义上的安全,让攻击者无法从密文中获取能助其破译的相关线索,避免遭受选择明文攻击法。
初始向量的值依密码算法而不同。最基本的要求是“唯一性”,也就是说同一把金钥不重复使用同一个初始向量。这个特性无论在区块加密或串流加密中都非常重要。
(3)对称密钥计算:每个服务分配的密钥(appsecret)
(4)对加密后的密文进行base64编码;
3.加密/解密代码实现
加密实现:
Cipher cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding"); SecretKeyFactory skf = SecretKeyFactory.getInstance("DESede"); SecretKey secretKey = skf.generateSecret(new DESedeKeySpec(key.getBytes())); IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes()); cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivParameterSpec); byte [] encryptData = cipher.doFinal(plainText.getBytes("utf-8")); String result = Base64.encode(encryptData);解密实现:
Cipher cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding"); SecretKeyFactory skf = SecretKeyFactory.getInstance("DESede"); SecretKey secretKey = skf.generateSecret(new DESedeKeySpec(key.getBytes())); IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes()); cipher.init(Cipher.DECRYPT_MODE, secretKey, ivParameterSpec); byte [] decryptData = cipher.doFinal(Base64.decode(encryptText)); String result = new String(decryptData, "utf-8");