文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Java实现常用的三种加密算法是什么

2023-06-29 17:00

关注

这篇文章主要为大家展示了“Java实现常用的三种加密算法是什么”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Java实现常用的三种加密算法是什么”这篇文章吧。

前言

编程中常见的加密算法有以下几种,它们在不同场景中分别有应用。除信息摘要算法外,其它加密方式都会需要密钥。

密钥

密钥(key,又常称金钥)是指某个用来完成加密解密完整性验证等密码学应用的秘密信息。

密钥分类

密钥和密码

密码一般是由用户生成,具有可读性,可以记忆和存储,常用于软件管理,而密钥是供实现加密算法的软件使用,不需要具备可读性(不过在编程中为了方便阅读都进行Base64)。我们也可以通过密码来生成密钥。

密钥管理

密钥生成

jdk 中 jce (Java Cryptography Extension) 包含了加密相关的所有API。

生成对称加密算法的密钥

Java实现常用的三种加密算法是什么

public static SecretKey generateKey(int keySize) {        KeyGenerator keyGenerator;        try {            keyGenerator = KeyGenerator.getInstance("AES");            keyGenerator.init(keySize);            return keyGenerator.generateKey();        } catch (NoSuchAlgorithmException e) {            // ignore            return null;        }    }

生成对称非对称加密算法的密钥

    public static PPKeys genKeysRSA(int keySize, SecureRandom random) throws NoSuchAlgorithmException {        KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");        if (null != random) {            generator.initialize(keySize, random);        } else {            generator.initialize(keySize);        }        KeyPair pair = generator.generateKeyPair();        PPKeys keys = new PPKeys();        PublicKey publicKey = pair.getPublic();        PrivateKey privateKey = pair.getPrivate();        keys.setPublicKey(Base64.getEncoder().encodeToString(publicKey.getEncoded()));      keys.setPrivateKey(Base64.getEncoder().encodeToString(privateKey.getEncoded()));        return keys;    }

密钥协商Diffie-Hellman

密钥协商是一种协议,两方或多方在通过该协议建立相同的共享密钥,然后通讯内容进行对称加密传输,而不需要交换密钥。

大致过程:每一方生成一个公私钥对并将公钥分发给其它方,当都获得其他方的公钥副本后就可以离线计算共享密钥。

Java中提供了 KeyAgreement 可以实现密钥协商。

Java实现常用的三种加密算法是什么

public static void diffieHellman() throws Exception {        AlgorithmParameterGenerator dhParams = AlgorithmParameterGenerator.getInstance("DH");        dhParams.init(1024);        KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DH");        keyGen.initialize(dhParams.generateParameters().getParameterSpec(DHParameterSpec.class), new SecureRandom());        KeyAgreement aliceKeyAgree = KeyAgreement.getInstance("DH");        KeyPair alicePair = keyGen.generateKeyPair();        KeyAgreement bobKeyAgree = KeyAgreement.getInstance("DH");        KeyPair bobPair = keyGen.generateKeyPair();        aliceKeyAgree.init(alicePair.getPrivate());        bobKeyAgree.init(bobPair.getPrivate());        aliceKeyAgree.doPhase(bobPair.getPublic(), true);        bobKeyAgree.doPhase(alicePair.getPublic(), true);       boolean agree = Base64.getEncoder().encodeToString(aliceKeyAgree.generateSecret()).equals(          Base64.getEncoder().encodeToString(bobKeyAgree.generateSecret())        );        System.out.println(agree);    }

信息摘要算法

信息摘要算法又叫加密散列算法,加密过程不需要密钥,常见的加密散列算法有MD系列SHA系列

一个理想的加密散列函数应该具备以下特性:

MD系列

MD5信息摘要算法(MD5 Message-Digest Algorithm),一种被广泛使用的加密散列函数,输出出一个128位(16字节)的散列值(hash value),MD5最初设计为加密散列函数,而目前发现它存在大量漏洞,所以不建议直接用作加密,不过在非加密场景下如:数据完整性校验,文件完整性校验它仍然有广泛的应用。

public static String md5(String content) {        try {            MessageDigest digest = MessageDigest.getInstance("MD5");            byte[] bytes = digest.digest(content.getBytes(StandardCharsets.UTF_8));            return Hex.encodeHexString(bytes);        } catch (final NoSuchAlgorithmException e) {            throw new IllegalArgumentException(e);        }    }

SHA系列

安全散列算法(Secure Hash Algorithm,缩写为SHA)是一个加密散列函数家族,是FIPS(美国联邦信息处理标准)所认证的安全散列算法。能计算出一个数字消息所对应到的,长度固定的字符串(又称消息摘要)的算法。且若输入的消息不同,它们对应到不同字符串的机率很高。

它们分别包含 SHA-0、SHA-1、SHA-2、SHA-3,其中 SHA-0、SHA-1 输出长度是160位,SHA-2 包含 SHA-224、SHA-256、SHA-384、SHA-512、SHA-512/224、SHA-512/256,我们平时常用 SHA-256 。

public static String sha256(String content) {        try {            MessageDigest digest = MessageDigest.getInstance("SHA-256);            byte[] bytes = digest.digest(content.getBytes(StandardCharsets.UTF_8));            return Hex.encodeHexString(bytes);        } catch (final NoSuchAlgorithmException e) {            throw new IllegalArgumentException(e);        }    }

对称加密算法

对称加密算法,双方持有相同密钥进行加解密,常见的对称加密算法:DES 3DES AES128 AES192 AES256。理解对称加密需要先明白下面几个概念:

DES

DES 是对称加密算法领域中的典型算法,因为密钥默认长度为56 bit,所以密码长度需要大于 8 byteDESKeySpec 取前 8 byte 进行密钥制作。

public static String encryptDES(byte[] content, String password) {        try {            SecureRandom random = new SecureRandom();            DESKeySpec desKeySpec = new DESKeySpec(password.getBytes());            SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("DES");            SecretKey secretKey = secretKeyFactory.generateSecret(desKeySpec);            Cipher cipher = Cipher.getInstance("DES");            cipher.init(Cipher.ENCRYPT_MODE, secretKey, random);            return Base64.getEncoder().encodeToString(cipher.doFinal(content));        } catch (Exception e) {            throw new RuntimeException(e);        }    }    public static String decryptDES(String content, String password) throws Exception {        SecureRandom random = new SecureRandom();        DESKeySpec desKeySpec = new DESKeySpec(password.getBytes());        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");        SecretKey secretKey = keyFactory.generateSecret(desKeySpec);        Cipher cipher = Cipher.getInstance("DES");        cipher.init(Cipher.DECRYPT_MODE, secretKey, random);        return new String(cipher.doFinal(Base64.getDecoder().decode(content)));    }

3DES

3DES(即Triple DES)。是DES算法的加强,它使用3条56位的密钥对数据进行三次加密。它以DES为基本模块,通过组合分组方法设计出分组加密算法。比起最初的DES,3DES更为安全。密钥默认长度 168 bit, 密码需要大于24 byte,IV 是 8 byte 的随机数字和字母数组。

public static String encrypt3DESECB(String content, String key, String iv) {        try {            IvParameterSpec ivSpec = new IvParameterSpec(iv.getBytes(StandardCharsets.UTF_8));            DESedeKeySpec dks = new DESedeKeySpec(key.getBytes(StandardCharsets.UTF_8));            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede");            SecretKey secretkey = keyFactory.generateSecret(dks);            Cipher cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");            cipher.init(Cipher.ENCRYPT_MODE, secretkey, ivSpec);            return Base64.getEncoder().encodeToString(cipher.doFinal(content.getBytes(StandardCharsets.UTF_8)));        } catch (Exception e) {            throw new RuntimeException(e);        }    }    public static String decrypt3DESECB(String content, String key, String iv) {        try {            IvParameterSpec ivSpec = new IvParameterSpec(iv.getBytes(StandardCharsets.UTF_8));            DESedeKeySpec dks = new DESedeKeySpec(key.getBytes(StandardCharsets.UTF_8));            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede");            SecretKey secretkey = keyFactory.generateSecret(dks);            Cipher cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");            cipher.init(Cipher.DECRYPT_MODE, secretkey, ivSpec);            return new String(cipher.doFinal(Base64.getDecoder().decode(content)), StandardCharsets.UTF_8);        } catch (Exception e) {            throw new RuntimeException(e);        }    }

AES

AES 高级数据加密标准,能够有效抵御已知的针对DES算法的所有攻击,默认密钥长度为128 bit,还可以供选择 192 bit256 bitAES-128 AES-192 AES-256

默认 AES-128 ,使用 PBEKeySpec 生成固定大小的密钥。

public static String encryptAES128(String plainText, String password, String salt) throws Exception {        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");        byte[] saltBytes = salt.getBytes(StandardCharsets.UTF_8);        // AES-128 密钥长度为128bit        PBEKeySpec spec = new PBEKeySpec(          password.toCharArray(),          saltBytes,          1000,          128        );        SecretKey secretKey = factory.generateSecret(spec);        SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(), "AES");        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");        AlgorithmParameters params = cipher.getParameters();        IvParameterSpec iv = params.getParameterSpec(IvParameterSpec.class);        cipher.init(Cipher.ENCRYPT_MODE, secret, iv);        byte[] encryptedTextBytes = cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8));        String encodedText = Base64.getEncoder().encodeToString(encryptedTextBytes);        String encodedIV = Base64.getEncoder().encodeToString(iv.getIV());        String encodedSalt = Base64.getEncoder().encodeToString(saltBytes);        return encodedSalt + "." + encodedIV + "." + encodedText;    }    public static String decryptAES128(String encryptedText, String password) throws Exception {        String[] fields = encryptedText.split("\\.");        byte[] saltBytes = Base64.getDecoder().decode(fields[0]);        byte[] ivBytes = Base64.getDecoder().decode(fields[1]);        byte[] encryptedTextBytes = Base64.getDecoder().decode(fields[2]);        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");        PBEKeySpec spec = new PBEKeySpec(          password.toCharArray(),          saltBytes,          1000,          128        );        SecretKey secretKey = factory.generateSecret(spec);        SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(), "AES");        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");        cipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(ivBytes));        byte[] decryptedTextBytes;        try {            decryptedTextBytes = cipher.doFinal(encryptedTextBytes);            return new String(decryptedTextBytes);        } catch (IllegalBlockSizeException | BadPaddingException e) {            throw new RuntimeException(e);        }    }

使用 AES-256 时可能会出现下面异常:

java.security.InvalidKeyException: Illegal key size

JDK 1.8.0_161 及以上版本默认已经启用无限强度加密:

static {        java.security.Security.setProperty("crypto.policy", "unlimited");    }

JDK 1.8.0_161以前版本需要手动安装 jce 策略文件(下载地址)

非对称加密算法

非对称加密使用一对密钥,公钥用作加密,私钥则用作解密。关于密钥大小,截至2020年,公开已知的最大RSA密钥是破解的是829位的RSA-250,建议至少使用 2048 位密钥。

Java实现常用的三种加密算法是什么

public static String encrypt(byte[] publicKey, String plainText) {        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKey);        KeyFactory kf;        try {            kf = KeyFactory.getInstance("RSA");            PublicKey publicKeySecret = kf.generatePublic(keySpec);            Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");            cipher.init(Cipher.ENCRYPT_MODE, publicKeySecret);            byte[] encryptedBytes = cipher.doFinal(plainText.getBytes());            return new String(Base64.getEncoder().encode(encryptedBytes));        } catch (Exception e) {            log.error("Rsa encrypt error ", e);            throw new RuntimeException(e);        }    }    public static String decrypt(byte[] privateKey, String encryptedText) {        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKey);        KeyFactory kf;        try {            kf = KeyFactory.getInstance("RSA");            PrivateKey privateKeySecret = kf.generatePrivate(keySpec);            Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");            cipher.init(Cipher.DECRYPT_MODE, privateKeySecret);            return new String(cipher.doFinal(Base64.getDecoder().decode(encryptedText)), StandardCharsets.UTF_8);        } catch (Exception e) {            log.error("Rsa decrypt error ", e);            throw new RuntimeException(e);        }    }

以上是“Java实现常用的三种加密算法是什么”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注编程网行业资讯频道!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     801人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     348人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     311人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     432人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     220人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯