RSA双向加解密(公钥加密-私钥解密;私钥加密-公钥解密)

这篇具有很好参考价值的文章主要介绍了RSA双向加解密(公钥加密-私钥解密;私钥加密-公钥解密)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

        非对称加密算法中,提供一个公钥一个私钥。一般情况下,采用公钥加密、私钥解密的方式。

        假设有这样一个场景:服务A与服务B需要通信,通信内容为了安全需要进行加密传输,并且服务A与服务B不能互相持有对方的钥匙。

        我首先想到的是能否利用RSA实现双向的加解密,查阅了资料后做了一个简单的实现,下面贴出实现原理及代码:文章来源地址https://www.toymoban.com/news/detail-510925.html

public class RsaEncryptUtil{
    public static final String PUBLIC_KEY="publicKey";
    public static final String PRIVATE_KEY="privateKey";
    private static final String KEY_STORE = "JKS";

    private static final int MAX_ENCRYPT_LENGTH = 117;
    private static final int MAX_DECRYPT_LENGTH = 128;

    /**
     * 随机生成RAS公钥与私钥字符串,直接返回
     */
    public static Map<String, String> getKeys() {
        KeyPairGenerator keyPairGen;
        try {
            keyPairGen = KeyPairGenerator.getInstance("RSA");
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            throw new RSAException("RSA获取钥匙对失败", e);
        }

        // 初始化密钥对生成器,密钥大小为96-1024位
        keyPairGen.initialize(1024,new SecureRandom());
        // 生成一个密钥对,保存在keyPair中
        KeyPair keyPair = keyPairGen.generateKeyPair();
        Map<String,String> keyMap = new HashMap<>();
        keyMap.put(PUBLIC_KEY, RSACryptUtil.base64ToStr(keyPair.getPublic().getEncoded()));
        keyMap.put(PRIVATE_KEY, RSACryptUtil.base64ToStr(keyPair.getPrivate().getEncoded()));

        return keyMap;
    }

    /**
     * 获得KeyStore
     *
     * @param keyStorePath
     * @param password
     */
    private static KeyStore getKeyStore(String keyStorePath, String password) throws Exception {
        FileInputStream is = new FileInputStream(keyStorePath);
        KeyStore ks = KeyStore.getInstance(KEY_STORE);
        ks.load(is, password.toCharArray());
        is.close();
        return ks;
    }

    /**
     * 由KeyStore获得私钥
     *
     * @param keyStorePath  KeyStore路径
     * @param alias         别名
     * @param storePass     KeyStore访问密码
     * @param keyPass       私钥的钥匙密码
     */
    private static PrivateKey loadPrivateKey(String keyStorePath, String alias, String storePass, String keyPass) throws Exception {
        KeyStore ks = getKeyStore(keyStorePath, storePass);
        PrivateKey key = (PrivateKey) ks.getKey(alias, keyPass.toCharArray());
        return key;
    }

    /**
     * 由Certificate获得公钥
     *
     * @param keyStorePath  KeyStore路径
     * @param alias         别名
     * @param storePass     KeyStore访问密码
     */
    private static PublicKey loadPublicKey(String keyStorePath, String alias, String storePass) throws Exception {
        KeyStore ks = getKeyStore(keyStorePath, storePass);
        PublicKey key = ks.getCertificate(alias).getPublicKey();
        return key;
    }


    /**
     * 公钥加密
     *
     * @param publicKey     公钥
     * @param content       明文数据
     */
    public static String encryptByPublic(String publicKey, String content){
        if (StringUtils.isEmpty(publicKey)) {
            throw new RSAException("加密公钥为空, 请设置");
        }
        if(StringUtils.isEmpty(content)){
            throw new RSAException("加密明文为空, 请设置");
        }
        Cipher cipher;
        StringBuilder result = new StringBuilder();
        try {
            // 使用默认RSA
            cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.ENCRYPT_MODE, RSACryptUtil.loadPublicKey(publicKey));
            byte[] bytes = content.getBytes();
            for (int i = 0; i < bytes.length; i += MAX_ENCRYPT_LENGTH) {
                byte[] subarray = ArrayUtils.subarray(bytes, i, i + MAX_ENCRYPT_LENGTH);
                if(subarray != null && subarray.length > 0){
                    byte[] doFinal = cipher.doFinal(subarray);
                    result.append(RSACryptUtil.base64ToStr(doFinal));
                }
            }
            return result.toString();
        } catch (NoSuchAlgorithmException e) {
            throw new RSAException("无此加密算法",e);
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
            return null;
        } catch (InvalidKeyException e) {
            throw new RSAException("加密公钥非法,请检查",e);
        } catch (IllegalBlockSizeException e) {
            throw new RSAException("明文长度非法",e);
        } catch (BadPaddingException e) {
            throw new RSAException("明文数据已损坏",e);
        } catch (Exception e) {
            throw new RSAException("未知错误",e);
        }
    }

    /**
     * 私钥解密
     *
     * @param privateKey    私钥
     * @param content       密文数据
     */
    public static String decryptByPrivate(String privateKey, String content){
        if (StringUtils.isEmpty(privateKey)) {
            throw new RSAException("解密私钥为空, 请设置");
        }
        if(StringUtils.isEmpty(content)){
            throw new RSAException("解密密文为空, 请设置");
        }
        if(content.length() < 4){
            throw new RSAException("解密密文有误:" + content);
        }
        Cipher cipher;
        StringBuilder result = new StringBuilder();
        try {
            // 使用默认RSA
            cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.DECRYPT_MODE, RSACryptUtil.loadPrivateKey(privateKey));
            byte[] bytes = RSACryptUtil.strToBase64(content);
            for (int i = 0; i < bytes.length; i += MAX_DECRYPT_LENGTH) {
                byte[] subarray = ArrayUtils.subarray(bytes, i, i + MAX_DECRYPT_LENGTH);
                if(subarray != null && subarray.length > 0){
                    byte[] doFinal = cipher.doFinal(subarray);
                    result.append(new String(doFinal));
                }
            }
            return result.toString();
        } catch (NoSuchAlgorithmException e) {
            throw new RSAException("无此解密算法",e);
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
            return null;
        } catch (InvalidKeyException e) {
            throw new RSAException("解密私钥非法,请检查");
        } catch (IllegalBlockSizeException e) {
            throw new RSAException("密文长度非法",e);
        } catch (BadPaddingException e) {
            throw new RSAException("密文数据已损坏",e);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RSAException("未知错误",e);
        }
    }


    /**
     * 私钥加密
     *
     * @param privateKey    私钥
     * @param content       明文数据
     */
    public static String encryptByPrivate(String privateKey,String content){
        if (StringUtils.isEmpty(privateKey)) {
            throw new RSAException("加密私钥为空, 请设置");
        }
        if(StringUtils.isEmpty(content)){
            throw new RSAException("加密明文为空, 请设置");
        }
        Cipher cipher;
        StringBuilder result = new StringBuilder();
        try {
            // 使用默认RSA
            cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.ENCRYPT_MODE, RSACryptUtil.loadPrivateKey(privateKey));
            byte[] bytes = content.getBytes();
            for (int i = 0; i < bytes.length; i += MAX_ENCRYPT_LENGTH) {
                byte[] subarray = ArrayUtils.subarray(bytes, i, i + MAX_ENCRYPT_LENGTH);
                if(subarray != null && subarray.length > 0){
                    byte[] doFinal = cipher.doFinal(subarray);
                    result.append(RSACryptUtil.base64ToStr(doFinal));
                }
            }
            return result.toString();
        }catch (NoSuchAlgorithmException e) {
            throw new RSAException("无此加密算法",e);
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
            return null;
        } catch (InvalidKeyException e) {
            throw new RSAException("加密私钥非法,请检查",e);
        } catch (IllegalBlockSizeException e) {
            throw new RSAException("明文长度非法",e);
        } catch (BadPaddingException e) {
            throw new RSAException("明文数据已损坏",e);
        }
    }


    /**
     * 公钥解密
     *
     * @param publicKey     公钥
     * @param content       密文数据
     */
    public static String decryptByPublic(String publicKey, String content){
        if (StringUtils.isEmpty(publicKey)) {
            throw new RSAException("解密公钥为空, 请设置");
        }
        if(StringUtils.isEmpty(content)){
            throw new RSAException("解密密文为空, 请设置");
        }
        if(content.length() < 4){
            throw new RSAException("解密密文有误:" + content);
        }
        Cipher cipher;
        StringBuilder result = new StringBuilder();
        try {
            // 使用默认RSA
            cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.DECRYPT_MODE, RSACryptUtil.loadPublicKey(publicKey));
            byte[] bytes = RSACryptUtil.strToBase64(content);
            for (int i = 0; i < bytes.length; i += MAX_DECRYPT_LENGTH) {
                byte[] subarray = ArrayUtils.subarray(bytes, i, i + MAX_DECRYPT_LENGTH);
                if(subarray != null && subarray.length > 0){
                    byte[] doFinal = cipher.doFinal(subarray);
                    result.append(new String(doFinal));
                }
            }
            return result.toString();
        }catch (NoSuchAlgorithmException e) {
            throw new RSAException("无此解密算法",e);
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
            return null;
        } catch (InvalidKeyException e) {
            throw new RSAException("解密公钥非法,请检查",e);
        } catch (IllegalBlockSizeException e) {
            throw new RSAException("密文长度非法",e);
        } catch (BadPaddingException e) {
            throw new RSAException("密文数据已损坏",e);
        }
    }
}

到了这里,关于RSA双向加解密(公钥加密-私钥解密;私钥加密-公钥解密)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 前端js使用jsrsasign,生成RSA秘钥,获取一系列信息(公钥,私钥,模数,指数等)进行加密解密

    前言: 之前的项目里用的RSA加解密的时候是生成固定的公钥(模数,指数)和私钥放在代码里进行数据的解密。现在要修改成前端自己生成(模数和指数)传给后台。后台加密数据返回给我。我在用私钥解密。 后面查了很多,开始的window.crypto里的方法可以生成公钥和私钥,

    2024年02月16日
    浏览(84)
  • RSA算法习题 (采用RSA算法,其中e=7,p=11,q=13,求出公钥和私钥,并求出明文85进行加密后的密文。)

    1、采用RSA算法,其中e=7,p=11,q=13,求出公钥和私钥,并求出明文85进行加密后的密文。 2. 找出质数 P、Q P=11 Q=13 3. 计算公共模数 N = P * Q = 143 4. 欧拉函数 Φ(N) = (P-1)*(Q-1) = 10 *12 = 120 5. 计算公钥E 1Eφ(N) 所以1E120 E的取值范围{3,7,9,11,13,17,19,...,117,119} E的取值必须和φ(N)互质 取

    2024年02月09日
    浏览(96)
  • 私钥和公钥到底是谁来加密、谁来解密?

    1.  应用场景 场景1(第一种用法):用于信息加解密,此时使用公钥加密,私钥解密。 场景2(第二种用法):用于数字签名,此时使用私钥签名,公钥验签。 有点混乱,不要去硬记,你只要这样想即可: - 既然是加密,那肯定是不希望别人知道我的消息,所以只有我才能解

    2023年04月15日
    浏览(78)
  • RSA加密,公钥、私钥的生成,前端使用公钥加密,JSEncrypt返回值为false的原因以及解决方法,XML转换Pkcs1、8

    非对称加密算法,两个且不同的Key,一个公开,一个私密,公开加密,私密解密。 特点: 原文短,加密后密文长 生成相对较慢 安全性超强 我们使用.net进行生成公钥、私钥。 使用RSA.ToXmlString(Boolean) 方法生成公钥以及私钥,方法中接收一个参数, true  表示同时包含 RSA 公钥

    2024年01月21日
    浏览(64)
  • 国密sm2公钥加密 私钥解密java代码实现

    目录 一、引入jar包 二、生成秘钥对,加解密工具类

    2024年02月11日
    浏览(71)
  • 使用非对称加密(RSA) 实现前端加密后端解密

    数据加密方式有: 单向加密、对称加密、非对称加密、加密盐、散列函数、数字签名。 1、单向加密 单向加密通过对数据进行摘要计算生成密文,密文不可逆推还原。只能加密,不能解密,常用于提取数据的指纹信息以此来验证数据的完整性。但是会引发雪崩效应(雪崩效应

    2024年02月08日
    浏览(68)
  • PHP非对称与对称双向加密解密的方式

    目录 RSA非对称加密解密: 什么是RSA非对称加密解密解析: 解析: 为什么使用: 有什么优点: DEMO: AES、DES、3DES等对称加密解密: 解析: 为什么使用: 有什么优点: DEMO: 什么是RSA非对称加密解密解析: 解析: RSA非对称加密解密算法是一种广泛应用于信息安全领域的加密算法。它不同于

    2024年02月07日
    浏览(75)
  • C# 实现对称加密算法(AES)与非对称加密算法(RSA),包含前端加密对应算法实现

    一种既简单速度又快的加密方式,加密与解密使用的都是同一个密钥,别名又叫做:单密钥加密;对称加密有很多公开算法,并且因为它效率很高,所以适用于加密大量数据的场合;但其密钥的传输过程是不安全的,并且容易被破解,密钥管理起来也相对麻烦。 需要两个密钥

    2024年02月09日
    浏览(67)
  • 20.2 OpenSSL 非对称RSA加解密算法

    RSA算法是一种非对称加密算法,由三位数学家 Rivest 、 Shamir 和 Adleman 共同发明,以他们三人的名字首字母命名。RSA算法的安全性基于大数分解问题,即对于一个非常大的合数,将其分解为两个质数的乘积是非常困难的。 RSA算法是一种常用的非对称加密算法,与对称加密算法

    2024年02月08日
    浏览(48)
  • 【openssl】RSA 生成公钥私钥 |通过私钥获取公钥

    通过博客:Window系统如何编译openssl 编译出openssl.exe(位于apps文件夹下)。 现在需要使用它获得公钥私钥、通过私钥获取公钥 目录 说明!!! 一.定位openssl.exe目录 二、进入命令cmd 三、生成私钥 四、已知的私钥替换模板私钥 五、通过私钥生成公钥 a.生成公钥私钥:跳过第四

    2024年02月04日
    浏览(64)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包