当前位置:

首页 > 编程开发 > Java实现常用的三种加密算法是什么

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

前言编程中常见的加密算法有以下几种,它们在不同场景中分别有应用。除信息摘要算法外,其它加密方式都会需要密钥。信息摘要算法对称加密算法非对称加密算法密钥密钥(key,又常称金钥)是指某个用来完成加密、解密、完整性验证等密码学应用的秘密信息。密钥分类加解密中的密钥:对称加密中共享相同的密钥,非对称加密中分公钥和私钥,公钥加密私钥解密。消息认证码和数字签名中的密钥:在消息认证码中,消息发送方和接收方使用共享密钥进行认证。在数字签名中,签名使用私钥,而验证使用公钥。会话密钥和主密钥:每次通信只使用一次的密钥称为会

    前言

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

    • 信息摘要算法

    • 对称加密算法

    • 非对称加密算法

    密钥

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

    密钥分类

    • 加解密中的密钥:对称加密中共享相同的密钥,非对称加密中分公钥私钥,公钥加密私钥解密。

    • 消息认证码和数字签名中的密钥:在消息认证码中,消息发送方和接收方使用共享密钥进行认证。在数字签名中,签名使用私钥,而验证使用公钥。

    • 会话密钥和主密钥:每次通信只使用一次的密钥称为会话密钥(session key)。相对于会话密钥,重复使用的密钥称为主密钥(master key)。

    密钥和密码

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

    密钥管理

    • 生成密钥:可以用随机数生成密钥,也可以用口令生成密钥。

    • 配送密钥:可采用事先共享密钥、使用密钥分配中心、使用公钥密码、使用Diffie-Hellman密钥交换。

    • 更新密钥

    • 保存密钥

    • 作废密钥

    密钥生成

    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;
            }
        }

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

    /**
         * 生成非对称密钥对
         *
         * @param keySize 密钥大小
         * @param random  指定随机来源,默认使用 JCAUtil.getSecureRandom()
         * @return 非对称密钥对
         * @throws NoSuchAlgorithmException NoSuchAlgorithm
         */
        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实现常用的三种加密算法是什么

    • Alice 和 Bob 分别用他们的私钥初始化自己的密钥协商对象 KeyAgreement ,调用init() 方法;

    • 然后将通信的每一方的公钥 传入执行 doPhase(Key key, boolean lastPhase) ;

    • 各方生成共享密钥 generateSecret()

    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。理解对称加密需要先明白下面几个概念:

    • 分组密码模式:将明文切割进行加密,再将密文拼接到一起。比如AES中会将明文数据切割为大小16字节的数据块,最后一块不够16字节时,使用Padding模式进行补充。

    • 填充(Padding):它有三种模式PKCS5、PKCS7和NOPADDING,PKCS5用缺少的字节数来填充,比如缺少5个字节就填充5个数字5,PKCS7缺少的字节数用0来填充。如果数据刚好是16的整数倍,PKCS5和PKCS7会再补充一个16字节数据来区分填充和有效数据,NOPADDING模式不需要填充。

    • 初始化向量:初始向量IV的作用是使加密更加安全可靠,在分组密码模式下IV大小对应数据块长度。

    • 加密模式:四种加密模式分别是:ECB(电子密码本模式)、CBC(密码分组链接模式)、CFB、OFB。ECB模式是仅仅使用明文和密钥来加密数据,所以该模式下不需要Padding,安全性也较弱,CBC模式数据分块并且使用传入IV依次进行异或操作,安全性也相对较高,所以目前一般都选择CBC模式。

    • 加密密钥:不同加密算法密钥长度不同,比如:DES 默认长度56位,3DES默认长度168位,也支持128位,AES默认128位,也支持192位,256位。我们一般根据密码生成密钥,密码长度需要满足算法密钥长度。

    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);
            }
        }
    本文内容来源于互联网,如有侵权请联系删除。
    作者最新文章
    编程开发
    相关文章 更多
    C++动态数组初始化怎么写?常用语句与代码示例
    C++动态数组初始化怎么写?常用语句与代码示例

    深入解析C++中动态数组的初始化机制,涵盖new操作符的不同用法、基本类型与类对象的初始化差异,以及为何在现代C++开发中应优先使用std::vector。

    谷歌浏览器Mac版入口
    谷歌浏览器Mac版入口

    谷歌浏览器Mac版官方安装指南 谷歌浏览器Mac版官方安装入口是https://www.google.com/chrome/,需macOS 12+系统、500MB空间,下载.dmg后拖入应用程序安装,支持多设备同步、性能优化与隐私保护功能。 苹果电脑Chrome的安装入口究竟在哪里?这个问题最近可是

    Chrome浏览器JS脚本不运行怎么办
    Chrome浏览器JS脚本不运行怎么办

    Chrome中JavaScript未执行需依次检查:一、移除站点级禁用并添加允许域名;二、开启全局JavaScript开关;三、禁用干扰扩展;四、在开发者工具中启用JavaScript;五、重置内容设置为默认。 有时在Chrome里打开网页,会发现交互按钮点了没反应,数据加载不出来,页面仿佛“静止”

    IE浏览器怀旧版在线网址
    IE浏览器怀旧版在线网址

    IE浏览器怀旧版在线网址:一次精准的技术时光回溯 最近,不少老用户和怀旧爱好者在反复搜索一个问题:那个经典的Internet Explorer,如今还能在哪里原汁原味地体验到?答案指向一个特定的地址:https://ie.microsoft.com/legacy/。 这个网站远不止是一个简单的“皮肤

    火狐浏览器有哪些设置功能
    火狐浏览器有哪些设置功能

    火狐浏览器五大核心设置功能:解锁高效、安全与个性化体验 火狐浏览器功能强大,但如果不仔细挖掘,很多能大幅提升效率和安全性的设置可能就“藏着掖着”了。这就好比拥有一台高性能设备,却只用了基础模式。那么,如何把它调整到最顺手、最安全的状态?接下来,我们就聚焦于当前版本(截至2025年末)最关键的五大设置

    chrome搜索免验证入口
    chrome搜索免验证入口

    Chrome官方免验证入口为https://www.google.cn/chrome/,提供全平台安装包、免登录即用、本地化安全机制及引擎级性能优化。 到底该去哪里找正版、免费且无需繁琐验证的Chrome浏览器入口?这个问题困扰了不少网友。今天,我们就来直通核心,为大家详细拆解Chrome引擎的官方

    java heap space 选型思路:使用场景与区别整理
    java heap space 选型思路:使用场景与区别整理

    Java堆是JVM存储对象的核心内存区域,配置需结合场景:单体应用适中设置;大数据处理需大堆并关注GC停顿;微服务强调快速启动;高并发需精细划分堆区域。关键参数-Xms和-Xmx建议等值以稳定性能。垃圾回收器选择影响效率,如G1适用于大堆,ZGC可实现低停顿。内存错误时需监控堆状态。

    java heap space 使用中遇到的问题怎么解决
    java heap space 使用中遇到的问题怎么解决

    Java堆内存溢出错误通常因内存泄漏、数据处理需求过大或JVM参数配置不当引起。排查时可借助jmap、堆转储及MAT等工具定位问题。解决方案包括调整JVM内存参数(如-Xmx)、修复代码中的内存泄漏、优化大数据处理逻辑,并建立持续监控与预防机制,以保障应用稳定运行。

    java xml 选型思路:使用场景与区别整理
    java xml 选型思路:使用场景与区别整理

    XML在Java开发中用于配置、数据交换等场景。解析方式主要有DOM、SAX、StAX及第三方库。DOM适合操作小文件,SAX/StAX适合处理大文件流,JAXB用于对象与XML映射。选型需结合数据大小、内存、性能及团队熟悉度,现代框架常封装底层解析。

    using namespace 使用中遇到的问题怎么解决
    using namespace 使用中遇到的问题怎么解决

    命名空间的基本概念与常见引入问题在C++等编程语言中,命名空间(namespace)是一种将代码标识符(如变量、函数、类名)封装在特定名称下的机制,其主要目的是避免命名冲突,尤其是在大型项目或使用多个第三方库时。使用“using namespace”指令可以将指定命名空间中的所有名称引入当前作用域,

    查看更多
    精品专题 更多
    装机必备
    装机必备

    正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

    Windows
    Windows

    正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

    macOS软件
    macOS软件

    正软商城macOS软件专区,精选适用于Mac电脑的办公、设计、影音、效率、开发和系统工具,提供软件功能介绍、macOS兼容版本、正版授权及购买下载服务。

    Mac软件 更多
    灵活计算器
    灵活计算器
    macOS/iOS/Android

    灵活计算器是一款笔记式算数应用,支持实时计算、动态关联和云端同步功能。记录、整理和输出之间的过渡会更自然,适合长期写作、做笔记或持续沉淀个人内容。

    赤友清理大师
    赤友清理大师
    macOS

    赤友清理大师是一款为 Mac 设计的智能清理优化工具,可精准扫描垃圾、大文件、重复文件等,释放磁盘空间。做扫描整理、文字提取和表格转换时,它能把识别后的处理步骤接得更顺,资料录入这类场景会省下不少时间。

    极度公式
    极度公式
    Windows/macOS/Linux

    极度公式是一款跨平台专业LaTeX公式识别编辑软件,支持OCR公式识别和多平台编辑。和使用说明,避免使用,享受完整功能与稳定支持。做扫描整理、文字提取和表格转换时,它能把识别后的处理步骤接得更顺,资料录入这类场景会省下不少时间。

    WINDOWS 更多
    Windows 10
    Windows 10
    Windows

    Windows 10 是一款微软推出的经典操作系统,拥有硬件兼容性与多任务处理能力。它更偏向把系统状态查看和常用调节动作放在一起,适合需要持续观察和微调设备状态的场景。

    极度公式
    极度公式
    Windows/macOS/Linux

    极度公式是一款跨平台专业LaTeX公式识别编辑软件,支持OCR公式识别和多平台编辑。和使用说明,避免使用,享受完整功能与稳定支持。做扫描整理、文字提取和表格转换时,它能把识别后的处理步骤接得更顺,资料录入这类场景会省下不少时间。

    密码键盘
    密码键盘
    Windows/macOS/iOS/Android

    密码键盘是一款兼具安全性与便捷性的高效密码管理器。日常使用里的持续防护和信息管理会更突出,适合把安全控制放进长期使用流程中的场景。