其实DES有很多同胞兄弟,如DESede(TripleDES)、AES、Blowfish、RC2、RC4(ARCFOUR)。这里就不过多阐述了,大同小异,只要换掉ALGORITHM换成对应的值,同时做一个代码替换SecretKey secretKey = new SecretKeySpec(key, ALGORITHM);就可以了,此外就是密钥长度不同了。
例:
import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; /** * DES算法类 * @author Povol */ public class DES { public static String encrypt(String encryptString, String encryptKey) throws Exception { SecretKeySpec key = new SecretKeySpec(encryptKey.getBytes(), "DES"); Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, key); byte[] encryptedData = cipher.doFinal(encryptString.getBytes()); return Base64.encode(encryptedData); } public static String decrypt(String decryptString, String decryptKey) throws Exception { byte[] byteMi = Base64.decode(decryptString); SecretKeySpec key = new SecretKeySpec(decryptKey.getBytes(), "DES"); Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding"); cipher.init(Cipher.DECRYPT_MODE, key); byte decryptedData[] = cipher.doFinal(byteMi); return new String(decryptedData); } }
密钥,长度必须是8位 。 !!! 还可以是其他的位数吗 ? 有实践过的给指导下谢谢 。。。
最近调整项目统一 php ios android 加密 修改 DES加密为 CBC分割模式 具体上代码 。
public class DES { private static byte[] iv1 = { (byte) 0x12, (byte) 0x34, (byte) 0x56, (byte) 0x78, (byte) 0x90, (byte) 0xAB, (byte) 0xCD, (byte) 0xEF }; public static String decrypt(String decryptString, String decryptKey) throws Exception { IvParameterSpec iv = new IvParameterSpec(iv1); SecretKeySpec key = new SecretKeySpec(decryptKey.getBytes(), "DES"); Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding"); cipher.init(Cipher.DECRYPT_MODE, key, iv); return new String(cipher.doFinal(Base64.decode(decryptString))); } public static String encrypt1(String encryptString, String encryptKey) throws Exception { IvParameterSpec iv = new IvParameterSpec(iv1); DESKeySpec dks = new DESKeySpec(encryptKey.getBytes()); SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); SecretKey key = keyFactory.generateSecret(dks); Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, key, iv); return Base64.encode(cipher.doFinal(encryptString.getBytes())); } }
网上解决方法
java.security.InvalidAlgorithmParameterException: ECB mode cannot use IV
ECB是什么呢?我的代码完全没有写ECB什么的
又上网搜索,结果把DES的来龙去脉都搞清楚了
http://www.tropsoft.com/strongenc/des.htm
ECB是其中一种字串分割方式,除了DES以外,其他加密方式也会使用这种分割方式的,而Java默认产生的DES算法就是用ECB方法,ECB不需要向量,当然也就不支持向量了
除了ECB,DES还支持CBC、CFB、OFB,而3DES只支持ECB和CBC两种
http://www.tropsoft.com/strongenc/des3.htm
CBC支持并且必须有向量,具体算法这里就不说了。合作商给的.net代码没有声明CBC模式,似乎是.net默认的方式就是CBC的
于是把模式改成CBC
Cipher cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
成功运行了
后话:
搜索的过程中,找到一个不错的讨论
http://www.lslnet.com/linux/dosc1/21/linux-197579.htm
在CBC(不光是DES算法)模式下,iv通过随机数(或伪随机)机制产生是一种比较常见的方法。iv的作用主要是用于产生密文的第一个block,以使最终生成的密文产生差异(明文相同的情况下),使密码攻击变得更为困难,除此之外iv并无其它用途。因此iv通过随机方式产生是一种十分简便、有效的途径。此外,在IPsec中采用了DES-CBC作为缺省的加密方式,其使用的iv是通讯包的时间戳。从原理上来说,这与随机数机制并无二致。
看来,向量的作用其实就是salt
最大的好处是,可以令到即使相同的明文,相同的密钥,能产生不同的密文
例如,我们用DES方式在数据保存用户密码的时候,可以另外增加一列,把向量同时保存下来,并且每次用不同的向量。这样的好处是,即使两个用户的密码是一样的,数据库保存的密文,也会不一样,就能降低猜测的可能性。