java实现非对称加密算法


前言

常用的RSA算法即为非对称加密算法。本文主要介绍什么是非对称加密以及java如何实现RSA加密与解密


一、什么是非对称密码体制

非对称密码体制的保密通信模型如下图
非对称密码算法通信模型
非对称密码体制有两个密钥,一个为公开的密钥(公钥),一个保密的密钥(私钥)。非对称密码体制的主要优点是可以适应开放性的使用环境,密钥管理问题相对简单,可以方便安全地实现数字签名和验证。RSA是非对称密码体制的典范。

二、非对称加密算法家谱

非对称面算法家谱

三、java实现RSA加密解密

1.通信模型

rsa通信模型

2.实现

sun实现与Bouncy Castle实现细节如下

算法密钥长度密钥长度默认值工作模式填充方式备注
RSA512~6553
(必须是64的倍数)
1024ECBNoPadding、PKCS1Padding
OAEPWITHMD5AndMGF1Padding
OAEPWITHSHA1AndMGF1Padding
OAEPWITHSHA256AndMGF1Padding等
jdk实现
RSA同上2048NONE同上Bouncy Castle实现
public class RSAUtil {
    private static final String KEY_ALGORITHM = "RSA";

    private static final String PUBLIC_KEY = "RSAPublicKey";

    private static final String PRIVATE_KEY = "RSAPrivateKey";

    private static final int KEY_SIZE = 512;

    /**
     * 初始化密钥
     *
     * @return map
     * @throws Exception Exception
     */
    public static Map<String, Object> initKey() throws Exception {
        // 实例化密钥对生成器
        KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);
        // 初始化密钥对生成器
        keyPairGen.initialize(KEY_SIZE);
        // 生成密钥对
        KeyPair keyPair = keyPairGen.generateKeyPair();
        // 公钥
        RSAPublicKey pubKey = (RSAPublicKey) keyPair.getPublic();
        // 私钥
        RSAPrivateKey priKey = (RSAPrivateKey) keyPair.getPrivate();
        Map<String, Object> keyMap = new HashMap<>();
        keyMap.put(PUBLIC_KEY, pubKey);
        keyMap.put(PRIVATE_KEY, priKey);
        return keyMap;
    }

    /**
     * 获取私钥
     *
     * @param keyMap keyMap
     * @return 私钥
     */
    public static byte[] getPrivateKey(Map<String, Object> keyMap) {
        return ((Key) keyMap.get(PRIVATE_KEY)).getEncoded();
    }

    /**
     * 获取公钥
     *
     * @param keyMap keyMap
     * @return 公钥
     */
    public static byte[] getPublicKey(Map<String, Object> keyMap) {
        return ((Key) keyMap.get(PUBLIC_KEY)).getEncoded();
    }

    /**
     * 私钥解密
     *
     * @param data 加密数据
     * @param key  密钥
     * @return 明文
     * @throws Exception Exception
     */
    public static byte[] decryptByPrivateKey(byte[] data, byte[] key) throws Exception {
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(key);
        KeyFactory factory = KeyFactory.getInstance(KEY_ALGORITHM);
        PrivateKey privateKey = factory.generatePrivate(keySpec);
        Cipher cipher = Cipher.getInstance(factory.getAlgorithm());
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        return cipher.doFinal(data);
    }

    /**
     * 公钥解密
     *
     * @param data 加密数据
     * @param key  密钥
     * @return 明文
     * @throws Exception Exception
     */
    public static byte[] decryptByPublicKey(byte[] data, byte[] key) throws Exception {
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(key);
        KeyFactory factory = KeyFactory.getInstance(KEY_ALGORITHM);
        PublicKey publicKey = factory.generatePublic(keySpec);
        Cipher cipher = Cipher.getInstance(factory.getAlgorithm());
        cipher.init(Cipher.DECRYPT_MODE, publicKey);
        return cipher.doFinal(data);
    }

    /**
     * 公钥加密
     *
     * @param data 明文
     * @param key  密钥
     * @return 明文
     * @throws Exception Exception
     */
    public static byte[] encryptByPublicKey(byte[] data, byte[] key) throws Exception {
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(key);
        KeyFactory factory = KeyFactory.getInstance(KEY_ALGORITHM);
        PublicKey publicKey = factory.generatePublic(keySpec);
        Cipher cipher = Cipher.getInstance(factory.getAlgorithm());
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        return cipher.doFinal(data);
    }

    /**
     * 私钥加密
     *
     * @param data 明文
     * @param key  密钥
     * @return 密文
     * @throws Exception Exception
     */
    public static byte[] encryptByPrivateKey(byte[] data, byte[] key) throws Exception {
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(key);
        KeyFactory factory = KeyFactory.getInstance(KEY_ALGORITHM);
        PrivateKey privateKey = factory.generatePrivate(keySpec);
        Cipher cipher = Cipher.getInstance(factory.getAlgorithm());
        cipher.init(Cipher.ENCRYPT_MODE, privateKey);
        return cipher.doFinal(data);
    }
}

3.测试

public class RSACoderTest {
    private byte[] publicKey;
    private byte[] privateKey;

    public static void main(String[] args) throws Exception {
        RSACoderTest coderTest = new RSACoderTest();
        coderTest.init();
        System.out.println("=========私钥加密,公钥解密begin=============");
        String plainTxt = "helloWorld";
        byte[] encryptData = RSAUtil.encryptByPrivateKey(plainTxt.getBytes(), coderTest.privateKey);
        System.out.println("加密后:" + Base64.encodeBase64String(encryptData));
        byte[] decryptData = RSAUtil.decryptByPublicKey(encryptData, coderTest.publicKey);
        System.out.println("解密后:" + new String(decryptData));
        System.out.println("=========私钥加密,公钥解密end=============");
        System.out.println("=========公钥加密,私钥钥解密begin=============");
        plainTxt = "worldHello";
        encryptData = RSAUtil.encryptByPublicKey(plainTxt.getBytes(), coderTest.publicKey);
        System.out.println("加密后:" + Base64.encodeBase64String(encryptData));
        decryptData = RSAUtil.decryptByPrivateKey(encryptData, coderTest.privateKey);
        System.out.println("解密后:" + new String(decryptData));
        System.out.println("=========公钥加密,私钥钥解密end=============");
    }

    private void init() throws Exception {
        Map<String, Object> keyMap = RSAUtil.initKey();
        publicKey = RSAUtil.getPublicKey(keyMap);
        privateKey = RSAUtil.getPrivateKey(keyMap);
        System.out.println("公钥:" + Base64.encodeBase64String(publicKey));
        System.out.println("私钥:" + Base64.encodeBase64String(privateKey));
    }
}

总结

目前,非对称加密算法(主要是RSA算法)主要应用于B2B等多种电子商务平台,但非对称加密算法并不直接对网络数据进行加密解密,而是用于交换对称加密算法的秘密密钥。最终使用对称加密算法进行真正的加密解密。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值