美文网首页
Java 密码API

Java 密码API

作者: 滨岩 | 来源:发表于2022-12-15 15:49 被阅读0次

对称加密相关API

image.png
/**
 * Aes 的Cipher 具体实现类是 AESCrypt
 *
 * @author huyanbing
 * @create 2022/12/16 2:39 下午
 */
public class AESTest {

    private final int keyLen;
    private final SecretKey key;

    private String algorithm = "AES";


    /**
     * 构造函数
     *
     * @param keyLen
     * @param plainKey
     */
    public AESTest(int keyLen, String plainKey) {
        //验证密钥长度是不是合规的
        assert keyLen == 128 || keyLen == 192 || keyLen == 256;
        this.keyLen = keyLen;
        if (plainKey == null) {
            key = generateKey();
        } else {
            key = importKey(plainKey);
        }
    }


    /**
     * 生成默认密钥
     *
     * @return
     */
    public SecretKey generateKey() {

        try {
            //静态工厂模式
            KeyGenerator keyGen = KeyGenerator.getInstance(algorithm);
            keyGen.init(keyLen);

            SecretKey key = keyGen.generateKey();
            return key;
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
    }


    /**
     * 导入密钥
     *
     * @param plainKey
     * @return
     */
    public SecretKey importKey(String plainKey) {

        byte[] keyBytes = plainKey.getBytes();

        //=>  keyLen/8
        assert keyBytes.length == keyLen >> 3;

        return new SecretKeySpec(keyBytes, algorithm);
    }


    /**
     * 一次加密
     *
     * @param plainText
     * @return
     * @throws Exception
     */
    public byte[] encrypt(byte[] plainText) throws Exception {

        Cipher aes = Cipher.getInstance(algorithm);

        //Cipher.ENCRYPT_MODE 1 加密模式
        aes.init(Cipher.ENCRYPT_MODE, key);

        //如果数据比较多,需要不断的调用aes.update 来 迭代你的数据, 如果数据比较少 直接调用doFinal就可以了
        //aes.update(plainText);

        return aes.doFinal(plainText);

    }

    /**
     * 一次解密
     *
     * @param cipherText
     * @return
     * @throws Exception
     */
    public byte[] decrypt(byte[] cipherText) throws Exception {

        Cipher aes = Cipher.getInstance(algorithm);
        aes.init(Cipher.DECRYPT_MODE, key);

        //aes.update(cipherText);

        return aes.doFinal(cipherText);
    }


    public static void main(String[] args) throws Exception {

//        AESTest test = new AESTest(128, null);

        AESTest test = new AESTest(128, "0123456789012345");
        //打印当前的 key
        String hex = HexCustomUtil.byteArrayToHexStr(test.key.getEncoded());

        System.out.println("---------key----------------");
        System.out.println(hex);


        //明文 PlainText
        byte[] plainText = "AES加密体制也是由多轮加密构成,除了结尾的一轮,其他轮都是由四个步骤组成——字节代替、行移位、列混淆、轮密钥加。而最后一轮仅包括字节代替、行移位、轮密钥加这三步。AES迭代的轮数与密钥的长度相关,16字节的密钥对应着迭代10轮,24字节的密钥对应着迭代12轮,32字节的密钥对应着迭代14轮。在开始所有轮迭代之前,需要进行一次初始变换——一次轮密钥加,这一步往往被称为第0轮。".getBytes();

        //加密
        byte[] cipherText = test.encrypt(plainText);

        //打印密文
        System.out.println("---------密文----------------");
        System.out.println(HexCustomUtil.byteArrayToHexStr(cipherText));


        byte[] decryptArr = test.decrypt(cipherText);

        System.out.println("---------解密后明文----------------");
        System.out.println(new String(decryptArr));


    }


}

public class HexCustomUtil {

    /*输入16进制byte[]输出16进制字符串*/
    public static String byteArrayToHexStr(byte[] byteArray) {
        if (byteArray == null) {
            return null;
        }
        char[] hexArray = "0123456789ABCDEF".toCharArray();
        char[] hexChars = new char[byteArray.length * 2];
        for (int j = 0; j < byteArray.length; j++) {
            int v = byteArray[j] & 0xFF;
            hexChars[j * 2] = hexArray[v >>> 4];
            hexChars[j * 2 + 1] = hexArray[v & 0x0F];
        }
        return new String(hexChars);
    }
}

相关文章

网友评论

      本文标题:Java 密码API

      本文链接:https://www.haomeiwen.com/subject/mmerqdtx.html