爱生活,爱分享


java加密-04 java实现对称加密算法

haiten 2019-10-12 606浏览 0条评论
首页/正文
分享到: / / / /

一、对称加密算法

DES

  • 3DES

AES

PBE

IDEA

对称加密算法为初等加密算法,安全性相对不高。

二、对称加密算法-DES

1、理论知识

DES(Data Encryption Standard)数据加密标准:

密钥长度 默认 工作模式 填充方式 实现方
56 56 ECB、CBC、PCBC、CTR、CTS、CFB、CFB8到128、OFB、OFB8到128 NoPadding、PKCS5Padding、ISO10126Padding JDK
64 56 同上 PKCS7Padding、ISO10126d2Padding、X932Padding、ISO7816d4Padding、ZeroBytePadding BC

2、JDK 实现:

public static void jdkDES() throws NoSuchAlgorithmException, InvalidKeyException, InvalidKeySpecException, NoSuchPaddingException, BadPaddingException, IllegalBlockSizeException, DecoderException {
    String src = "test source";

    // 生成KEY
    KeyGenerator keyGenerator = KeyGenerator.getInstance("DES");
    keyGenerator.init(56);
    // 根据指定算法生成默认长度的密钥
    // keyGenerator.init(new SecureRandom());
    System.out.println(keyGenerator.getProvider());
    Key key = keyGenerator.generateKey();
    byte[] keyBytes = key.getEncoded();

    // KEY转换
    KeySpec desKeySpec = new DESKeySpec(keyBytes);
    SecretKeyFactory factory = SecretKeyFactory.getInstance("DES");
    System.out.println(factory.getProvider());
    Key convertKey = factory.generateSecret(desKeySpec);

    // 加密
    Cipher enCipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
    enCipher.init(Cipher.ENCRYPT_MODE, convertKey);
    byte[] encode = enCipher.doFinal(src.getBytes());
    // Hex 编码
    String encodeHex = Hex.encodeHexString(encode);
    System.out.println(enCipher.getProvider() + "- des encrypt(Hex):" + encodeHex);
    // Base64 编码
    String encodeBase64 = Base64.encodeBase64String(encode);
    System.out.println(enCipher.getProvider() + "- des encrypt(Base64):" + encodeBase64);

    // 解密
    Cipher deCipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
    deCipher.init(Cipher.DECRYPT_MODE, convertKey);
     byte[] decode = deCipher.doFinal(encode);
    // byte[] decode = deCipher.doFinal(Hex.decodeHex(encodeHex));
    // byte[] decode = deCipher.doFinal(Base64.decodeBase64(encodeBase64));
    System.out.println(deCipher.getProvider() + "- des decrypt:" + new String(decode));
}

3、Bouncy Castle 实现:

public static void bcDES() throws NoSuchProviderException, NoSuchAlgorithmException, InvalidKeyException, InvalidKeySpecException, NoSuchPaddingException, BadPaddingException, IllegalBlockSizeException {
    String src = "test source";

    // 设置 BC 的提供Provider
    Security.addProvider(new BouncyCastleProvider());

    // 生成KEY
    KeyGenerator keyGenerator = KeyGenerator.getInstance("DES","BC");
    keyGenerator.init(56);
    // 根据指定算法生成默认长度的密钥
    // keyGenerator.init(new SecureRandom());
    System.out.println(keyGenerator.getProvider());
    Key key = keyGenerator.generateKey();
    byte[] keyBytes = key.getEncoded();

    // KEY转换
    KeySpec desKeySpec = new DESKeySpec(keyBytes);
    SecretKeyFactory factory = SecretKeyFactory.getInstance("DES","BC");
    System.out.println(factory.getProvider());
    Key convertKey = factory.generateSecret(desKeySpec);

    // 加密
    Cipher enCipher = Cipher.getInstance("DES/ECB/PKCS5Padding","BC");
    enCipher.init(Cipher.ENCRYPT_MODE, convertKey);
    byte[] encode = enCipher.doFinal(src.getBytes());
    // Hex 编码
    String encodeHex = Hex.encodeHexString(encode);
    System.out.println(enCipher.getProvider() + "- des encrypt(Hex):" + encodeHex);
    // Base64 编码
    String encodeBase64 = Base64.encodeBase64String(encode);
    System.out.println(enCipher.getProvider() + "- des encrypt(Base64):" + encodeBase64);

    // 解密
    Cipher deCipher = Cipher.getInstance("DES/ECB/PKCS5Padding","BC");
    deCipher.init(Cipher.DECRYPT_MODE, convertKey);
    byte[] decode = deCipher.doFinal(encode);
    // byte[] decode = deCipher.doFinal(Hex.decodeHex(encodeHex));
    // byte[] decode = deCipher.doFinal(Base64.decodeBase64(encodeBase64));
    System.out.println(deCipher.getProvider() + "- des decrypt: " + new String(decode));
}

三、对称加密算法-3重DES

1、理论知识

出现缘由:

1、DES违反柯克霍夫原则

2、安全问题(怀疑存在后门)

3重DES的好处:

1、密钥长度增强

2、迭代次数提高

3、3重DES的应用十分广泛

密钥长度 默认 工作模式 填充方式 实现方
112、168 168 ECB、CBC、PCBC、CTR、CTS、CFB、CFB8到128、OFB、OFB8到128 Nopadding、PKCS5Padding、ISO10126Padding JDK
168、192 168 同上 PKCS7Padding、ISO10126d2Padding、X932Padding、ISO7816d4Padding、ZeroBytePadding BC

2、JDK 实现:

public static void jdk3DES() throws NoSuchAlgorithmException, InvalidKeyException, InvalidKeySpecException, NoSuchPaddingException, BadPaddingException, IllegalBlockSizeException {
    String src = "test source";

    // 生成KEY
    KeyGenerator keyGenerator = KeyGenerator.getInstance("DESede");
    keyGenerator.init(168);
    // 根据指定算法生成默认长度的密钥
    // keyGenerator.init(new SecureRandom());
    System.out.println(keyGenerator.getProvider());
    Key key = keyGenerator.generateKey();
    byte[] keyBytes = key.getEncoded();

    // KEY转换
    KeySpec desKeySpec = new DESedeKeySpec(keyBytes);
    SecretKeyFactory factory = SecretKeyFactory.getInstance("DESede");
    System.out.println(factory.getProvider());
    Key convertKey = factory.generateSecret(desKeySpec);

    // 加密
    Cipher enCipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");
    enCipher.init(Cipher.ENCRYPT_MODE, convertKey);
    byte[] encode = enCipher.doFinal(src.getBytes());
    // Hex 编码
    String encodeHex = Hex.encodeHexString(encode);
    System.out.println(enCipher.getProvider() + "- 3des encrypt(Hex): " + encodeHex);
    // Base64 编码
    String encodeBase64 = Base64.encodeBase64String(encode);
    System.out.println(enCipher.getProvider() + "- 3des encrypt(Base64): " + encodeBase64);

    // 解密
    Cipher deCipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");
    deCipher.init(Cipher.DECRYPT_MODE, convertKey);
    byte[] decode = deCipher.doFinal(encode);
    // byte[] decode = deCipher.doFinal(Hex.decodeHex(encodeHex));
    // byte[] decode = deCipher.doFinal(Base64.decodeBase64(encodeBase64));
    System.out.println(deCipher.getProvider() + "- 3des decrypt: " + new String(decode));
}

3、Bouncy Castle 实现:

public static void bc3DES() throws NoSuchProviderException, NoSuchAlgorithmException, InvalidKeyException, InvalidKeySpecException, NoSuchPaddingException, BadPaddingException, IllegalBlockSizeException {
    String src = "test source";

    // 设置 BC 的提供Provider
    Security.addProvider(new BouncyCastleProvider());

    // 生成KEY
    KeyGenerator keyGenerator = KeyGenerator.getInstance("DESede","BC");
    keyGenerator.init(168);
    // 根据指定算法生成默认长度的密钥
    // keyGenerator.init(new SecureRandom());
    System.out.println(keyGenerator.getProvider());
    Key key = keyGenerator.generateKey();
    byte[] bytesKey = key.getEncoded();

    // KEY转换
    KeySpec desKeySpec = new DESedeKeySpec(bytesKey);
    SecretKeyFactory factory = SecretKeyFactory.getInstance("DESede","BC");
    System.out.println(factory.getProvider());
    Key convertKey = factory.generateSecret(desKeySpec);

    // 加密
    Cipher enCipher = Cipher.getInstance("DESede/ECB/PKCS5Padding","BC");
    enCipher.init(Cipher.ENCRYPT_MODE, convertKey);
    byte[] encode = enCipher.doFinal(src.getBytes());
    // Hex 编码
    String encodeHex = Hex.encodeHexString(encode);
    System.out.println(enCipher.getProvider() + "- 3des encrypt(Hex): " + encodeHex);
    // Base64 编码
    String encodeBase64 = Base64.encodeBase64String(encode);
    System.out.println(enCipher.getProvider() + "- 3des encrypt(Base64): " + encodeBase64);

    // 解密
    Cipher deCipher = Cipher.getInstance("DESede/ECB/PKCS5Padding","BC");
    deCipher.init(Cipher.DECRYPT_MODE, convertKey);
    byte[] decode = deCipher.doFinal(encode);
    // byte[] decode = deCipher.doFinal(Hex.decodeHex(encodeHex));
    // byte[] decode = deCipher.doFinal(Base64.decodeBase64(encodeBase64));
    System.out.println(deCipher.getProvider() + " - 3des decrypt: " + new String(decode));
}

四、对称加密算法-AES

1、理论知识

加解密效率高,DES替代者:

AES是目前使用最多的对称加密算法;

AES的优势之一是至今尚未被破解;

AES通常用于移动通信系统加密以及基于SSH协议的软件(SSH Client、secureCRT);

密钥长度 默认 工作模式 填充方式 实现方
128、192、256 128 ECB、CBC、PCBC、CTR、CTS、CFB、CFB8到128、OFB、OFB8到128 Nopadding、PKCS5Padding、ISO10126Padding JDK(256位密钥需要获得无政策限制权限文件)
同上 同上 同上 PKCS7Padding、ZeroBytePadding BC

无政策限制权限文件是指,因为某些国家的进口管制限制,Java发布的运行环境包中的加解密有一定的限制。

2、JDK 实现:

public static void jdkAES() throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, DecoderException {
    String src = "test source";

    // 生成KEY
    KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
    keyGenerator.init(128);
    // 根据指定算法生成默认长度的密钥
    // keyGenerator.init(new SecureRandom());
    System.out.println(keyGenerator.getProvider());
    Key key = keyGenerator.generateKey();
    byte[] keyBytes = key.getEncoded();

    // KEY转换
    Key convertKey = new SecretKeySpec(keyBytes, "AES");

    // 加密
    Cipher enCipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
    enCipher.init(Cipher.ENCRYPT_MODE, convertKey);
    byte[] encode = enCipher.doFinal(src.getBytes());
    // Hex 编码
    String encodeHex = Hex.encodeHexString(encode);
    System.out.println(enCipher.getProvider() + "- aes encrypt(Hex):" + encodeHex);
    // Base64 编码
    String encodeBase64 = Base64.encodeBase64String(encode);
    System.out.println(enCipher.getProvider() + "- aes encrypt(Base64):" + encodeBase64);

    // 解密
    Cipher deCipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
    deCipher.init(Cipher.DECRYPT_MODE, convertKey);
    byte[] decode = deCipher.doFinal(encode);
    // byte[] decode = deCipher.doFinal(Hex.decodeHex(encodeHex));
    // byte[] decode = deCipher.doFinal(Base64.decodeBase64(encodeBase64));
    System.out.println(deCipher.getProvider() + "- aes decrypt:" + new String(decode));
}

3、Bouncy Castle 实现:

public static void bcAES() throws NoSuchProviderException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
    String src = "test source";

    // 设置 BC 的提供Provider
    Security.addProvider(new BouncyCastleProvider());

    // 生成KEY
    KeyGenerator keyGenerator = KeyGenerator.getInstance("AES","BC");
    keyGenerator.init(128);
    // 根据指定算法生成默认长度的密钥
    // keyGenerator.init(new SecureRandom());
    System.out.println(keyGenerator.getProvider());
    Key key = keyGenerator.generateKey();
    byte[] keyBytes = key.getEncoded();

    // KEY转换
    Key convertKey = new SecretKeySpec(keyBytes, "AES");

    // 加密
    Cipher enCipher = Cipher.getInstance("AES/ECB/PKCS5Padding","BC");
    enCipher.init(Cipher.ENCRYPT_MODE, convertKey);
    byte[] encode = enCipher.doFinal(src.getBytes());
    // Hex 编码
    String encodeHex = Hex.encodeHexString(encode);
    System.out.println(enCipher.getProvider() + "- aes encrypt(Hex):" + encodeHex);
    // Base64 编码
    String encodeBase64 = Base64.encodeBase64String(encode);
    System.out.println(enCipher.getProvider() + "- aes encrypt(Base64):" + encodeBase64);

    // 解密
    Cipher deCipher = Cipher.getInstance("AES/ECB/PKCS5Padding","BC");
    deCipher.init(Cipher.DECRYPT_MODE, convertKey);
    byte[] decode = deCipher.doFinal(encode);
    // byte[] decode = deCipher.doFinal(Hex.decodeHex(encodeHex));
    // byte[] decode = deCipher.doFinal(Base64.decodeBase64(encodeBase64));
    System.out.println(deCipher.getProvider() + "- aes decrypt:" + new String(decode));
}

五、对称加密算法-PBE

1、理论知识

PBE 不是一种全新的算法,而是对现有已有的算法的整合封装:

AES、DES和3重DES在使用上比较一致;

PBE算法结合了消息摘要算法和对称加密算法的优点;

BPE(Password Based Encrytion)基于口令加密(加盐);

算法 密钥长度 默认 工作模式 填充方式 实现方
PBEWithMD5AndDES 56 56 CBC PKCS5Padding JDK
PBEWithMD5AndTripleDES 112、168 168 同上 同上 同上
PBEWithSHA1AndDESede 112、168 168 同上 同上 同上
PBEWithSHA1AndRC2_40 40~1024(8倍数) 128 同上 同上 同上
PBEWithMD5AndDES 64 64 CBC PKCS5Padding、PKCS7Padding、ISO10126Padding、ZeroBytePadding BC
PBEWithMD5AndRC2 128 128 同上 同上 同上
PBEWithSHA1AndDES 64 64 同上 同上 同上
PBEWithSHA1AndRC2 128 128 同上 同上 同上
PBEWithSHAAndIDEA-CBC 128 128 同上 同上 同上
PBEWithSHAAnd2-KeyTripleDES-CBC 128 128 同上 同上 同上
PBEWithSHAAnd3-KeyTripleDES-CBC 192 192 同上 同上 同上

2、JDK 实现:

    public static void jdkPBE() throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
        String src = "test source";

        // 初始化盐
        SecureRandom random = new SecureRandom();
        byte[] salt = random.generateSeed(8);
        PBEParameterSpec pbeParameterSpec = new PBEParameterSpec(salt, 100);

        // 口令与密码
        String password = "imooc";
        PBEKeySpec pbeKeySpec = new PBEKeySpec(password.toCharArray());
        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
        Key key = factory.generateSecret(pbeKeySpec);

        // 加密
        Cipher enCipher = Cipher.getInstance("PBEWithMD5AndDES");
        enCipher.init(Cipher.ENCRYPT_MODE, key, pbeParameterSpec);
        byte[] encode = enCipher.doFinal(src.getBytes());
        // Hex 编码
        String encodeHex = Hex.encodeHexString(encode);
        System.out.println(enCipher.getProvider() + "- pbe encrypt(Hex):" + encodeHex);
        // Base64 编码
        String encodeBase64 = Base64.encodeBase64String(encode);
        System.out.println(enCipher.getProvider() + "- pbe encrypt(Base64):" + encodeBase64);

        // 解密
        Cipher deCipher = Cipher.getInstance("PBEWithMD5AndDES");
        deCipher.init(Cipher.DECRYPT_MODE, key, pbeParameterSpec);
        byte[] decode = deCipher.doFinal(encode);
        // byte[] decode = deCipher.doFinal(Hex.decodeHex(encodeHex));
        // byte[] decode = deCipher.doFinal(Base64.decodeBase64(encodeBase64));
        System.out.println(deCipher.getProvider() + "- pbe decrypt:" + new String(decode));
    }

3、Bouncy Castle 实现:

    public static void bcPBE() throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchProviderException, NoSuchPaddingException, InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
        String src = "test source";

        // 设置 BC 的提供Provider
        Security.addProvider(new BouncyCastleProvider());

        // 初始化盐
        SecureRandom random = new SecureRandom();
        byte[] salt = random.generateSeed(8);
        PBEParameterSpec pbeParameterSpec = new PBEParameterSpec(salt, 100);

        // 口令与密码
        String password = "imooc";
        PBEKeySpec pbeKeySpec = new PBEKeySpec(password.toCharArray());
        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBEWithMD5AndDES","BC");
        Key key = factory.generateSecret(pbeKeySpec);

        // 加密
        Cipher enCipher = Cipher.getInstance("PBEWithMD5AndDES","BC");
        enCipher.init(Cipher.ENCRYPT_MODE, key, pbeParameterSpec);
        byte[] encode = enCipher.doFinal(src.getBytes());
        // Hex 编码
        String encodeHex = Hex.encodeHexString(encode);
        System.out.println(enCipher.getProvider() + "- pbe encrypt(Hex):" + encodeHex);
        // Base64 编码
        String encodeBase64 = Base64.encodeBase64String(encode);
        System.out.println(enCipher.getProvider() + "- pbe encrypt(Base64):" + encodeBase64);

        // 解密
        Cipher deCipher = Cipher.getInstance("PBEWithMD5AndDES","BC");
        deCipher.init(Cipher.DECRYPT_MODE, key, pbeParameterSpec);
        byte[] decode = deCipher.doFinal(encode);
        // byte[] decode = deCipher.doFinal(Hex.decodeHex(encodeHex));
        // byte[] decode = deCipher.doFinal(Base64.decodeBase64(encodeBase64));
        System.out.println(deCipher.getProvider() + "- pbe decrypt:" + new String(decode));
    }

六、其它

当加密和解密不在同一方时:

把密钥特殊处理后发给对方;

双方约定密钥;

主要知识点来源于慕课慕课网上 moocer老师 提供的 java 加密系列教程。 原创不易,如需转载,请标明出处!

最后修改:2019-10-12 11:28:27 © 著作权归作者所有
如果觉得我的文章对你有用,请随意赞赏
扫一扫支付

上一篇

发表评论

说点什么吧~

评论列表

还没有人评论哦~赶快抢占沙发吧~