对称加密算法 PBE

概念

PBE算法(Password Based Encryption基于口令加密)是一种基于口令的加密算法,其特点是使用口令代替了密钥,而口令由用户自己掌管,采用随机数杂凑多重加密等方法保证数据的安全性。

加密过程

PBE算法在加密过程中并不是直接使用口令来加密,而是加密的密钥由口令生成,这个功能由PBE算法中的KDF函数完成。KDF函数的实现过程为:将用户输入的口令首先通过“盐”(salt)的扰乱产生准密钥,再将准密钥经过散列函数多次迭代后生成最终加密密钥,密钥生成后,PBE算法再选用对称加密算法对数据进行加密,可以选择DES、3DES、RC5等对称加密算法 。

java jdk 实现

PbeUtils.java

package crypto.pbe;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;
import java.security.SecureRandom;

/**
 * 对称加密 PBE算法 java实现
 */
public class PbeUtils {

    /**
     * @link {https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#Algorithms}
     */
    private static final String ALGORITHM = "PBEWITHMD5andDES";

    /**
     * 获取随机的8字节长的盐值
     */
    public static byte[] getSalt() {
        return getSalt(8);
    }

    /**
     * 获取随机的 numBytes 字节长的盐值
     *
     * @param numBytes 盐值的字节长度
     */
    public static byte[] getSalt(int numBytes) {
        SecureRandom random = new SecureRandom();
        byte[] salt = random.generateSeed(numBytes);
        return salt;
    }


    /**
     * @param password 口令
     */
    private static SecretKey getKey(String password) throws Exception {
        PBEKeySpec pbeKeySpec = new PBEKeySpec(password.toCharArray());
        SecretKeyFactory factory = SecretKeyFactory.getInstance(ALGORITHM);
        SecretKey secretKey = factory.generateSecret(pbeKeySpec);
        return secretKey;
    }

    public static byte[] encrypt(String password, byte[] data) throws Exception {
        return encrypt(password, new byte[]{0, 0, 0, 0, 0, 0, 0, 0}, 100, data);
    }

    /**
     * 加密
     *
     * @param password       口令
     * @param salt           盐值
     * @param data           需要加密的数据
     * @param iterationCount 迭代次数
     */
    public static byte[] encrypt(String password, byte[] salt, int iterationCount, byte[] data) throws Exception {
        PBEParameterSpec pbeParameterSpec = new PBEParameterSpec(salt, iterationCount);
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, getKey(password), pbeParameterSpec);
        byte[] bytes = cipher.doFinal(data);
        return bytes;
    }

    public static byte[] decrypt(String password, byte[] data) throws Exception {
        return decrypt(password, new byte[]{0, 0, 0, 0, 0, 0, 0, 0}, 100, data);
    }

    /**
     * 解密
     *
     * @param password       口令
     * @param salt           盐值
     * @param data           需要解密的数据
     * @param iterationCount 迭代次数
     */
    public static byte[] decrypt(String password, byte[] salt, int iterationCount, byte[] data) throws Exception {
        PBEParameterSpec pbeParameterSpec = new PBEParameterSpec(salt, iterationCount);
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, getKey(password), pbeParameterSpec);
        return cipher.doFinal(data);
    }

}

package crypto.pbe;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.Hex;

public class PbeUtilsTest {

    public static void main(String[] args) throws Exception {
        String text = "世界人民大团结万岁";
        byte[] salt = PbeUtils.getSalt();
        System.out.println("盐值:" + Hex.encodeHexString(salt));
        String password = "123456";// 口令
        int iterationCount = 10;

        byte[] encryptBytes = PbeUtils.encrypt(password, salt, iterationCount, text.getBytes());
        System.out.println("密文:" + Base64.encodeBase64String(encryptBytes));
        byte[] result = PbeUtils.decrypt(password, salt, iterationCount, encryptBytes);
        System.out.println("解密:" + new String(result));
    }
}

code

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我会尽力回答您的问题。 PBE(Password-Based Encryption)口令加密是一种基于口令的加密方式,它通过使用用户输入的口令来生成加密密钥,从而实现数据加密。PBE口令加密算法有很多,其中包括使用MD5消息摘要算法和TripleDES对称加密算法PBE口令加密算法。下面我将简单介绍一下这种算法的实现和验证过程。 1. 算法实现 首先,我们需要使用MD5消息摘要算法对口令进行摘要处理,生成128位的摘要值。然后,我们使用生成的摘要值作为密钥,使用TripleDES对称加密算法对要加密的数据进行加密。 下面是一个简单的Java实现示例: ```java import javax.crypto.Cipher; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.DESedeKeySpec; import java.security.MessageDigest; import java.security.SecureRandom; public class PBECipher { private static final int ITERATIONS = 1000; private static final int KEY_LENGTH = 192; public static byte[] encrypt(String password, byte[] data) throws Exception { SecureRandom random = new SecureRandom(); byte[] salt = new byte[8]; random.nextBytes(salt); SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); SecretKey key = factory.generateSecret(new DESedeKeySpec(getKey(password.toCharArray(), salt))); Cipher cipher = Cipher.getInstance("DESede"); cipher.init(Cipher.ENCRYPT_MODE, key); byte[] encrypted = cipher.doFinal(data); MessageDigest md = MessageDigest.getInstance("MD5"); md.update(password.getBytes()); md.update(salt); md.update(encrypted); byte[] digest = md.digest(); byte[] output = new byte[encrypted.length + digest.length + salt.length]; System.arraycopy(encrypted, 0, output, 0, encrypted.length); System.arraycopy(digest, 0, output, encrypted.length, digest.length); System.arraycopy(salt, 0, output, encrypted.length + digest.length, salt.length); return output; } public static boolean verify(String password, byte[] encryptedData) throws Exception { byte[] encrypted = new byte[encryptedData.length - 16 - 8]; byte[] digest = new byte[16]; byte[] salt = new byte[8]; System.arraycopy(encryptedData, 0, encrypted, 0, encryptedData.length - 16 - 8); System.arraycopy(encryptedData, encryptedData.length - 16 - 8, digest, 0, 16); System.arraycopy(encryptedData, encryptedData.length - 8, salt, 0, 8); SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); SecretKey key = factory.generateSecret(new DESedeKeySpec(getKey(password.toCharArray(), salt))); MessageDigest md = MessageDigest.getInstance("MD5"); md.update(password.getBytes()); md.update(salt); md.update(encrypted); byte[] newDigest = md.digest(); if (!MessageDigest.isEqual(digest, newDigest)) { return false; } Cipher cipher = Cipher.getInstance("DESede"); cipher.init(Cipher.DECRYPT_MODE, key); byte[] decrypted = cipher.doFinal(encrypted); return MessageDigest.isEqual(decrypted, encryptedData); } private static byte[] getKey(char[] password, byte[] salt) throws Exception { SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); return factory.generateSecret(new DESedeKeySpec(password)).getEncoded(); } } ``` 2. 算法验证 为了验证这个算法是否正确,我们需要编写一个测试程序,生成随机的数据,使用口令加密后再进行解密,并与原始数据进行比较。如果解密后的数据与原始数据相同,则说明加密算法正确。 下面是一个简单的Java测试程序示例: ```java import java.security.SecureRandom; import java.util.Arrays; public class PBECipherTest { public static void main(String[] args) throws Exception { SecureRandom random = new SecureRandom(); byte[] data = new byte[1024]; random.nextBytes(data); String password = "password"; byte[] encrypted = PBECipher.encrypt(password, data); System.out.println("Original Data: " + Arrays.toString(data)); System.out.println("Encrypted Data: " + Arrays.toString(encrypted)); boolean verified = PBECipher.verify(password, encrypted); System.out.println("Verification Result: " + verified); } } ``` 运行测试程序后,如果输出的Verification Result为true,则说明这个算法实现是正确的。 希望这个回答能够帮到您。如果您还有任何问题,请随时提出。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值