栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java使用PBE算法进行对称加解密最简入门和示例

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java使用PBE算法进行对称加解密最简入门和示例

PBE 算法

PBE( Password based Encryption, 基于口密加密)。PBE是一种基于口令的加密算法, 采用随机数杂凑(盐)多重加密方法保证数据安全性。
PBE算法并没有真正构建新的算法, 而是对现有对称加密算法(比如DES)进行了包装。

因为密钥很长,一般 由算法产生, 比如DES密钥长度56; 口令一般比较短, 可以容易记住, 也就是我们平时所说的密码。口令很容易通过穷举攻击被破译, 所以就引入了“盐”。
盐本身是一个随机信息, 相同的随机信息不可能使用两次, 将盐加载口令上, 通过消息摘要算法迭代计算构建密钥, 破译就比较难了。

Java 对PBE算法的实现

JDK本身提供了对PBE算法的实现,不需要导入其他的第三方库。 Java中的PBE算法是对各种消息摘要算法(比如MD5,SHA)和对称加密算法(比如DES,RC2)的组合。 比如 PBEWithMD5AndDES算法。
PBEWithMD5AndDES的密钥长度是56 , 是组合了MD5和DES算法。

示例代码

本篇示例环境:

  • JDK1.8
  • Eclipse IDE

因为示例需要使用base64对字节数组和字符串进行转换,所以需要导入base64的包,这个包在本地JRE的lib 目录下, 导入方式如下图:

这里将加密和解密放在一起, 实际项目中可以分开来放, 完整代码如下:

import java.security.Key;
import java.security.SecureRandom;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;

import sun.misc.base64Decoder;
import sun.misc.base64Encoder;
public class PBEDemo {
	  
    public static final String ALGORITHM = "PBEWITHMD5andDES";

     
    public static byte[] initSalt() throws Exception { 
        SecureRandom random = new SecureRandom();//实例化安全随机数
        return random.generateSeed(8);//产出盐
    }
    
    private static Key toKey(String password) throws Exception {
        PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray());
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM);
        SecretKey secretKey = keyFactory.generateSecret(keySpec);
        return secretKey;
    }

    
    public static byte[] encrypt(byte[] data, String password, byte[] salt)
            throws Exception {
        Key key = toKey(password);
        PBEParameterSpec paramSpec = new PBEParameterSpec(salt, 100);
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, key, paramSpec);
        return cipher.doFinal(data);
    }

    
    public static byte[] decrypt(byte[] data, String password, byte[] salt)
            throws Exception {
        Key key = toKey(password);
        PBEParameterSpec paramSpec = new PBEParameterSpec(salt, 100);
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, key, paramSpec);
        return cipher.doFinal(data);
    }

    
   public static byte[] decryptbase64(String key) throws Exception {
       return (new base64Decoder()).decodeBuffer(key);
  }

    
    public static String encryptbase64(byte[] key) throws Exception {
		return (new base64Encoder()).encodeBuffer(key);
   }


	public static void main(String[] args) throws Exception {
		String message = "你好";
		String password = "oscar999";
		//1. 加密
		byte[] salt = initSalt();
		byte[] encryBytes = encrypt(message.getBytes(),password,salt);
		String encryStr = encryptbase64(encryBytes);
		String saltStr = encryptbase64(salt);
		System.out.println("原文="+message);
		System.out.println("盐="+saltStr);
		System.out.println("密文="+encryStr);
		
		
		//2. 解密
		encryBytes = decryptbase64(encryStr);
		salt = decryptbase64(saltStr);
		byte[] decryBytes = decrypt(encryBytes,password,salt);
		System.out.println("解密后="+new String(decryBytes));
	}

}

说明:

  1. 加密和解密返回的类型都是byte[], 通过base64编码转换为可显示字串。上面方法的decryptbase64() 和encryptbase64() 用于字符串和字符数组类型的转换。
  2. 盐必须为8个字节, 盐可以随机产生,也可以是双方按一定规律约定的消息(比如按时间), 也可以是一个固定的号码。
错误解决 Exception in thread “main” javax.crypto.IllegalBlockSizeException: Input length must be multiple of 8 when decrypting with padded cipher

盐的值不对

相关知识参考
  • base64是一种基于64个可打印字符来表示二进制数据的表示方法, 相关参考:base64 编码介绍
    • MD5 , 全称是Message-Digest Algorithm 5, 是一种消息摘要算法。关于消息摘要, 可以参考消息摘要(Message Digest)及其算法
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/659019.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号