千家信息网

Java非对称加密算法RSA怎么实现

发表于:2025-11-07 作者:千家信息网编辑
千家信息网最后更新 2025年11月07日,本篇内容主要讲解"Java非对称加密算法RSA怎么实现",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"Java非对称加密算法RSA怎么实现"吧!一、非对称加
千家信息网最后更新 2025年11月07日Java非对称加密算法RSA怎么实现

本篇内容主要讲解"Java非对称加密算法RSA怎么实现",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"Java非对称加密算法RSA怎么实现"吧!

一、非对称加密

非对称加密算法是一种密钥的保密方法。

非对称加密算法需要两个密钥:公开密钥(publickey:简称公钥)和私有密钥(privatekey:简称私钥)。公钥与私钥是一对,如果用公钥对数据进行加密,只有用对应的私钥才能解密。因为加密和解密使用的是两个不同的密钥,所以这种算法叫作非对称加密算法。 非对称加密算法实现机密信息交换的基本过程是:甲方生成一对密钥并将公钥公开,需要向甲方发送信息的其他角色(乙方)使用该密钥(甲方的公钥)对机密信息进行加密后再发送给甲方;甲方再用自己私钥对加密后的信息进行解密。甲方想要回复乙方时正好相反,使用乙方的公钥对数据进行加密,同理,乙方使用自己的私钥来进行解密。

另一方面,甲方可以使用自己的私钥对机密信息进行签名后再发送给乙方;乙方再用甲方的公钥对甲方发送回来的数据进行验签。

甲方只能用其私钥解密由其公钥加密后的任何信息。 非对称加密算法的保密性比较好,它消除了最终用户交换密钥的需要。

非对称密码体质的特点:算法强度复杂、安全性依赖于算法与密钥但是由于其算法复杂,而使得加密解密速度没有对称加密解密的速度快。对称密码体制中只有一种密钥,并且是非公开的,如果要解密就得让对方知道密钥。所以保证其安全性就是保证密钥的安全,而非对称密钥体制有两种密钥,其中一个是公开的,这样就可以不需要像对称密码那样传输对方的密钥了。这样安全性就大了很多。

二、RSA算法

简介:

RSA公开密钥密码体质是一种使用不同的加密密钥与解密密钥,"由已知加密密钥推导出解密密钥在计算上是不可行的"密码体制 。

在公开密钥密码体制中,加密密钥(即公开密钥)PK是公开信息,而解密密钥(即秘密密钥)SK是需要保密的。加密算法E和解密算法D也都是公开的。虽然解密密钥SK是由公开密钥PK决定的,但却不能根据PK计算出SK 。

正是基于这种理论,1978年出现了著名的RSA算法,它通常是先生成一对RSA密钥,其中之一是保密密钥,由用户保存;另一个为公开密钥,可对外公开,甚至可在网络服务器中注册。为提高保密强度,RSA密钥至少为500位长,一般推荐使用1024位。这就使加密的计算量很大。为减少计算量,在传送信息时,常采用传统加密方法与公开密钥加密方法相结合的方式,即信息采用改进的DES或IDEA对话密钥加密,然后使用RSA密钥加密对话密钥和信息摘要。对方收到信息后,用不同的密钥解密并可核对信息摘要 。

RSA是被研究得最广泛的公钥算法,从提出到现在已近三十年,经历了各种攻击的考验,逐渐为人们接受,普遍认为是目前最优秀的公钥方案之一。1983年麻省理工学院在美国为RSA算法申请了专利。

算法原理:

RSA公开密钥密码体制的原理是:根据数论,寻求两个大素数比较简单,而将它们的乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥 。

RSA允许你选择公钥的大小。512位的密钥被视为不安全的;768位的密钥不用担心受到除了国家安全管理(NSA)外的其他事物的危害;1024位的密钥几乎是安全的。RSA在一些主要产品内部都有嵌入,像 Windows、网景 Navigator、 Quicken和 Lotus Notes 。

三、RSA算法Java语言实现

RSA算法工具类源码:

package com.ljt.rsa.util;import org.apache.commons.codec.binary.Base64;import org.apache.commons.io.IOUtils;import javax.crypto.Cipher;import java.io.ByteArrayOutputStream;import java.security.*;import java.security.interfaces.RSAPrivateKey;import java.security.interfaces.RSAPublicKey;import java.security.spec.InvalidKeySpecException;import java.security.spec.PKCS8EncodedKeySpec;import java.security.spec.X509EncodedKeySpec;import java.util.HashMap;import java.util.Map;/** * @ClassName: RSAUtil * @Description:  RSA非对称加密算法工具类 * @Author: 寒山月初°C * @Date 2021/5/16 17:47 * @Version 1.0 */public class RSAUtil {    public static final String CHARSET = "UTF-8";    public static final String RSA_ALGORITHM = "RSA";    public static Map createKeys(int keySize){        //为RSA算法创建一个KeyPairGenerator对象(KeyPairGenerator,密钥对生成器,用于生成公钥和私钥对)        KeyPairGenerator kpg;        try{            kpg = KeyPairGenerator.getInstance(RSA_ALGORITHM);        }catch(NoSuchAlgorithmException e){            throw new IllegalArgumentException("No such algorithm-->[" + RSA_ALGORITHM + "]");        }        //初始化KeyPairGenerator对象,密钥长度        kpg.initialize(keySize);        //生成密匙对        KeyPair keyPair = kpg.generateKeyPair();        //得到公钥        Key publicKey = keyPair.getPublic();        String publicKeyStr = Base64.encodeBase64URLSafeString(publicKey.getEncoded()); //返回一个publicKey经过二次加密后的字符串        //得到私钥        Key privateKey = keyPair.getPrivate();        String privateKeyStr = Base64.encodeBase64URLSafeString(privateKey.getEncoded()); 返回一个privateKey经过二次加密后的字符串        Map keyPairMap = new HashMap();        keyPairMap.put("publicKey", publicKeyStr);        keyPairMap.put("privateKey", privateKeyStr);        return keyPairMap;    }    /**     * 得到公钥     * @param publicKey 密钥字符串(经过base64编码)     * @throws Exception     */    public static RSAPublicKey getPublicKey(String publicKey) throws NoSuchAlgorithmException, InvalidKeySpecException {        //通过X509编码的Key指令获得公钥对象        KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(Base64.decodeBase64(publicKey));        RSAPublicKey key = (RSAPublicKey) keyFactory.generatePublic(x509KeySpec);        return key;    }    /**     * 得到私钥     * @param privateKey 密钥字符串(经过base64编码)     * @throws Exception     */    public static RSAPrivateKey getPrivateKey(String privateKey) throws NoSuchAlgorithmException, InvalidKeySpecException {        //通过PKCS#8编码的Key指令获得私钥对象        KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKey));        RSAPrivateKey key = (RSAPrivateKey) keyFactory.generatePrivate(pkcs8KeySpec);        return key;    }    /**     * 公钥加密     * @param data     * @param publicKey     * @return     */    public static String publicEncrypt(String data, RSAPublicKey publicKey){        try{            Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);            cipher.init(Cipher.ENCRYPT_MODE, publicKey);            return Base64.encodeBase64URLSafeString(rsaSplitCodec(cipher, Cipher.ENCRYPT_MODE, data.getBytes(CHARSET), publicKey.getModulus().bitLength()));        }catch(Exception e){            throw new RuntimeException("加密字符串[" + data + "]时遇到异常", e);        }    }    /**     * 私钥解密     * @param data     * @param privateKey     * @return     */    public static String privateDecrypt(String data, RSAPrivateKey privateKey){        try{            Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);            cipher.init(Cipher.DECRYPT_MODE, privateKey);            return new String(rsaSplitCodec(cipher, Cipher.DECRYPT_MODE, Base64.decodeBase64(data), privateKey.getModulus().bitLength()), CHARSET);        }catch(Exception e){            throw new RuntimeException("解密字符串[" + data + "]时遇到异常", e);        }    }    /**     * 私钥加密     * @param data     * @param privateKey     * @return     */    public static String privateEncrypt(String data, RSAPrivateKey privateKey){        try{            Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);            cipher.init(Cipher.ENCRYPT_MODE, privateKey);            return Base64.encodeBase64URLSafeString(rsaSplitCodec(cipher, Cipher.ENCRYPT_MODE, data.getBytes(CHARSET), privateKey.getModulus().bitLength()));        }catch(Exception e){            throw new RuntimeException("加密字符串[" + data + "]时遇到异常", e);        }    }    /**     * 公钥解密     * @param data     * @param publicKey     * @return     */    public static String publicDecrypt(String data, RSAPublicKey publicKey){        try{            Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);            cipher.init(Cipher.DECRYPT_MODE, publicKey);            return new String(rsaSplitCodec(cipher, Cipher.DECRYPT_MODE, Base64.decodeBase64(data), publicKey.getModulus().bitLength()), CHARSET);        }catch(Exception e){            throw new RuntimeException("解密字符串[" + data + "]时遇到异常", e);        }    }    private static byte[] rsaSplitCodec(Cipher cipher, int opmode, byte[] datas, int keySize){        int maxBlock = 0;        if(opmode == Cipher.DECRYPT_MODE){            maxBlock = keySize / 8;        }else{            maxBlock = keySize / 8 - 11;        }        ByteArrayOutputStream out = new ByteArrayOutputStream();        int offSet = 0;        byte[] buff;        int i = 0;        try{            while(datas.length > offSet){                if(datas.length-offSet > maxBlock){                    buff = cipher.doFinal(datas, offSet, maxBlock);                }else{                    buff = cipher.doFinal(datas, offSet, datas.length-offSet);                }                out.write(buff, 0, buff.length);                i++;                offSet = i * maxBlock;            }        }catch(Exception e){            throw new RuntimeException("加解密阀值为["+maxBlock+"]的数据时发生异常", e);        }        byte[] resultDatas = out.toByteArray();        IOUtils.closeQuietly(out);        return resultDatas;    }}

编写测试类:

class Test{    public static void main (String[] args) throws Exception {        Map keyMap = RSAUtil.createKeys(1024);        String  publicKey = keyMap.get("publicKey");        String  privateKey = keyMap.get("privateKey");        System.out.println("公钥: " + publicKey);        System.out.println("私钥: " + privateKey);        System.out.println("公钥加密--私钥解密");        String str = "寒山月初℃";        System.out.println("明文:" + str);        System.out.println("明文大小:" + str.getBytes().length);        String encodedData = RSAUtil.publicEncrypt(str, RSAUtil.getPublicKey(publicKey));        System.out.println("密文:" + encodedData);        String decodedData = RSAUtil.privateDecrypt(encodedData, RSAUtil.getPrivateKey(privateKey));        System.out.println("解密后文字: " + decodedData);    }}

运行结果:

公钥:
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCyrF0HBVsYdA2fTy1iYIWh7j1OoCDzLiBWomWO3Ngn1ajl2wSPk05E7yINxLiTaQSA0H86EWv0jRJrGSdg6kwqzhWv53hza4xEXozLNgDR5L0bxEAmtv1abFALwpMHMPr8NzbpvXHwNaHer6mBrhXDVuyPdgZkWuh0kLrpvXHetQIDAQAB
私钥:
MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBALKsXQcFWxh0DZ9PLWJghaHuPU6gIPMuIFaiZY7c2CfVqOXbBI-TTkTvIg3EuJNpBIDQfzoRa_SNEmsZJ2DqTCrOFa_neHNrjERejMs2ANHkvRvEQCa2_VpsUAvCkwcw-vw3Num9cfA1od6vqYGuFcNW7I92BmRa6HSQuum9cd61AgMBAAECgYA5KNch9d6stgPdoVDdlg9qPHM0ghnIcks6K_3ddF1acQn1btnIrNFvUClOyk5aKlCcfRcWlpg4xiDMTmHAqXPv_H2AQTqqLdhKC6cz0AZDuiv_itO40rqmvi9n0lcJWP0zq3cJyNlE8ogNsb9heHn_XdPIxD4tdl3QztZQHBfOgQJBAObDr9SBD0EsiGCeULMEj-hEOHsMh0NANpHvNdzKj9xNb28fAZ4H8reRG5frUqpCSTkxgigBwsMhYeQu_ebNoAUCQQDGNl8iVw219K0e3Awwd7TUmM8Ugt8intD1rbYObsYDZlss6rzsm0XzUgkJE9X6xcdu_O5jWZ49mgC3i-jg7HLxAkBZ9h383VdiFAdSi0VwlK25YacXKUouCIF9oODBo2I0AygXDOJnhje0Imi8b-v5HgBHwKo6CH2x7nioKT2oVa81AkByl8KedtfNZ1yjJ7LAXqSj-IhYImVgfZLvRnOnmnFOS-HQcRGydP6W8smYfuhJ6Agp6X7k30317VAWzYNgbjLxAkEAvOYGU33Ll871QFzWTW8eHg1SJMP4oTL3jKuQi5lVMrZTWoCQF_wvuHKAKgIs0AzFwh6vrkNN1fv5QASzwtIGzg
公钥加密--私钥解密
明文:
寒山月初℃
明文大小:
15
密文:
pnQYCefqnlYLZ2wuMcxsbkD9feA3WFcDXShYx6HajvlsriQGWzb4Xxdwz0KTzjz3nqho9AxUc2bZmBhq05v-DCyB14u2NyabENuMXoiKft4QGKNVG3WxGps55xRHr3lVt4Rj59mDBX_manNsQDwxj7gy_Brv6Uv_NRzd6M91aGk
解密后文字:
寒山月初℃ Process finished with exit code 0

到此,相信大家对"Java非对称加密算法RSA怎么实现"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

0