网站建设的五类成员,学编程的培训机构,外国购物网站大全,dell网站的网站设计特色1.对称加密算法定义#xff1a;数据发送方将原始数据和加密密钥经过特殊加密算法处理后#xff0c;将加密密文发送出去。接收方收到密文后#xff0c;需要使用加密用过的密钥及相同算法的逆算法对密文进行解密#xff0c;才能使其恢复成可读明文。 2.在对称加密算法中…1.对称加密算法定义数据发送方将原始数据和加密密钥经过特殊加密算法处理后将加密密文发送出去。接收方收到密文后需要使用加密用过的密钥及相同算法的逆算法对密文进行解密才能使其恢复成可读明文。 2.在对称加密算法中使用的密钥只有一个双方都使用这个密钥对数据进行加密和解密 常用的对称加密算法DES、3DESTripleDES和AES 常用的加密模式是ECB电子密码本模式、CBC加密分组链接模式 常用的填充方式是NoPadding不填充、Zeros填充0填充、PKCS5Padding填充 3.注意以下区别 3.1.不同的加密算法,其工作密钥不同且产生密钥工厂的算法名不同 DES有很多同胞兄弟如DESede(TripleDES)、AES大同小异 1密钥长度不同 DES固定工作密钥为8个字节共64位 AES固定工作密钥为16/24/32bytes。 2在产生密钥工厂时只要换掉ALGORITHM换成对应的值就行SecretKey secretKey new SecretKeySpec(key, ALGORITHM) 3.2加密模式不同初始化的随机也不同 ECB采用分组加密的方式将明文按8字节64位分组分别加密。 CBC的处理方式是先用初始向量IV对第一组加密再用第一组的密文作为密钥对第二组加密然后依次完成整个加密操作。如果明文中有两个分组的内容相同ECB会得到完全一样的密文但CBC则不会。 DES下的cbc模式下的pkcs5padding可以用初始向量IV加密也能用SecureRandom,但是aes必须用初始向量 在初始化向量参数时AES 为16bytes. DES 为8bytes. 3.3填充方式不同 如果没有指定默认的方式就是PKCS5Padding 大部分情况下明文并非刚好64位的倍数。对于最后一个分组如果长度小于64位则需要用数据填充至64位。 PKCS7Padding是缺几个字节就补几个字节的0 PKCS5Padding是缺几个字节就补充几个字节的几好比缺6个字节就补充6个字节的6 4.有可能出现的错误 1java.security.InvalidKeyException: Wrong key size工作密钥为8个字节共64位 2javax.crypto.BadPaddingException: Given final block not properly padded 原因是Cipher cipher Cipher.getInstance(DES); 等同于Cipher cipher Cipher.getInstance(DES/ECB/PKCS5Padding)一样填充方式错误加密的时候会得到16长度的字节数组。
/*简单Des算法加密解密使用ECB/NoPadding主要参数有工作密钥为8个字节共64位数据为8个字节共64位指定工作方式ECB/NoPadding且随机数用new SecureRandom()*/
public class DesEcbNopaddingSafety {public static void main(String[] args) {String data 12345678;String key 12345678;byte[] encryData encrydata(data, key);String encryD new Base64().encodeAsString(encryData);System.out.println(加密后的数据是 encryD);byte[] decodeD new Base64().decode(encryD);byte[] descryData bytedecryData(decodeD, key);String d new String(descryData);System.out.println(解密后的数据是 d);}private static byte[] bytedecryData(byte[] decodeD, String key) {// TODO Auto-generated method stubbyte[] deData null;try {SecretKeyFactory keyFactory SecretKeyFactory.getInstance(DES);DESKeySpec dks new DESKeySpec(key.getBytes());SecretKey securekey keyFactory.generateSecret(dks);Cipher cipher Cipher.getInstance(DES/ECB/NoPadding);SecureRandom random new SecureRandom();cipher.init(Cipher.ENCRYPT_MODE, securekey, random);deData cipher.doFinal(decodeD);} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}return deData;}private static byte[] encrydata(String data, String key) {// TODO Auto-generated method stubbyte[] encryData null;try {// 创建一个密钥工厂SecretKeyFactory keyfactory SecretKeyFactory.getInstance(DES);// 根据原始密钥数据创建密钥对象DESKeySpec使用 key 中的前 8 个字节作为 DES 密钥的密钥内容DESKeySpec dks new DESKeySpec(key.getBytes());// 在用密钥工厂把DESKeySpec变成规范的密钥对象SecretKeySecretKey securekey keyfactory.generateSecret(dks);// 生成一个可信任的随机数源SecureRandom random new SecureRandom();// 通过Cipher.getInstance()工厂方法来实例化密码对象。Cipher cipher Cipher.getInstance(DES/ECB/NoPadding);// 用密钥、算法参数和随机源初始化此Cipher密码对象cipher.init(Cipher.DECRYPT_MODE, securekey, random);// 执行加密encryData cipher.doFinal(data.getBytes());} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}return encryData;}
}pre namecode classjava
加密后的数据是9ejp64Hyi3M
解密后的数据是12345678/*使用DES/CBC/PKCS5Padding加密且随机数用new IvParameterSpec(iv1)*/
public class DesCbcPkcs5Safety {public static void main(String[] args) {String data 1234578;String key 12345678;byte[] encryData encrydata(data, key);String encryD new Base64().encodeAsString(encryData);System.out.println(加密后的数据是 encryD);byte[] decodeD new Base64().decode(encryD);byte[] descryData bytedecryData(decodeD, key);String d new String(descryData);System.out.println(解密后的数据是 d);}private static byte[] bytedecryData(byte[] decodeD, String key) {// TODO Auto-generated method stubbyte[] deData null;try {SecretKeyFactory keyFactory SecretKeyFactory.getInstance(DES);DESKeySpec dks new DESKeySpec(key.getBytes());SecretKey securekey keyFactory.generateSecret(dks);Cipher cipher Cipher.getInstance(DES/CBC/PKCS5Padding);// 这里使用的是向量。采用此代码中的IVParameterSpecIvParameterSpec iv new IvParameterSpec(iv1);cipher.init(Cipher.DECRYPT_MODE, securekey, iv);deData cipher.doFinal(decodeD);} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}return deData;}private static byte[] encrydata(String data, String key) {// TODO Auto-generated method stubbyte[] encryData null;try {Cipher cipher Cipher.getInstance(DES/CBC/PKCS5Padding);SecretKeyFactory keyfactory SecretKeyFactory.getInstance(DES);SecretKey securekey keyfactory.generateSecret(new DESKeySpec(key.getBytes()));// 注意这里使用的是向量IvParameterSpec iv new IvParameterSpec(iv1);cipher.init(Cipher.ENCRYPT_MODE, securekey, iv);encryData cipher.doFinal(data.getBytes());} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}return encryData;}private static byte[] iv1 { (byte) 0x12, (byte) 0x34, (byte) 0x56,(byte) 0x78, (byte) 0x90, (byte) 0xAB, (byte) 0xCD, (byte) 0xEF };
}加密后的数据是DXCyuKP3IWQ
解密后的数据是12345785.主要步骤如下 (1).利用SecretKeyFactory.getInstance(加密算法)创建密钥工厂 (2).用new DESKeySpec(原始密钥)产生密钥对象 (3).用密钥工厂的generateSecret(密钥对象)方法把密钥对象转换成规范的密钥对象 (4).用new SecureRandom()或者用 new IvParameterSpec(向量)生成一个可信任的随机数源 (5).用Cipher.getInstance(加密算法/加密模式/填充模式)产生加密解密对象 (6).用cipher.init(加密解密模型规范密钥随机数)初始化加密解密对象 (7).用cipher.doFinal(数据)执行加密解密操作