RSA算法(非对称加密算法)的JAVA实现案例及总结

目录

对称式加密算法总结

非对称式加密算法概述

非对称加密算法的优缺点

案例实现

总结


对称式加密算法总结

对称加密(也叫私钥加密)指加密和解密使用相同密钥的加密算法,在大多数的对称算法中,加密密钥和解密密钥是相同的,所以也称这种加密算法为单密钥算法

对称加密算法的特点是算法公开、计算量小、加密速度快、加密效率高。不足之处是,交易双方都使用同样钥匙,那么如果在网络上传输时,被黑客劫取到了密钥,那么就会造成严重的安全性漏洞。所以对称加密算法的安全性得不到保证。

非对称式加密算法概述

非对称式加密: 加密和解密使用不同的密钥。例如,用户A密钥加密后所得到的信息,只能用用户A的解密密钥才能解密。如果知道了其中一个,并不能计算出另外一个。因此,如果公开了密钥对中的一个密钥,并不会危害到另外一个的秘密性质。

我们将这个公开的密钥称为公钥;不能公开的密钥称为私钥,只有同一对公私钥,才能正常加密和解密。

从DH算法我们可以看到,公钥-私钥组成的密钥对是非常有用的加密方式,因为公钥是可以公开的,而私钥是完全保密的,由此奠定了非对称加密的基础。

非对称加密的典型算法就是RSA算法,它是由Ron Rivest,Adi Shamir,Leonard Adleman这三个人一起发明的,所以用他们三个人的姓氏首字母缩写表示。

非对称加密算法的优缺点

优点: 首先,毋庸置疑,非对称加密算法的加解密过程更加安全,即使公钥被劫获,也不影响私钥的保密性。

缺点: 既然使用不同的密钥进行加解密,那么它的运算速度肯定会大打折扣,相对于对称加密算法来说,它慢得多。

案例实现

现有小明和小红,小明要加密一个明文发给小红,按照非对称加密算法,他首先应该获取小红的公钥,然后用小红的公钥加密,把加密结果发送给小红,此密文只能由小红的私钥才能解开。由于小红的私钥一直在自己手里,没有进行任何传输动作,所以除了小红没有人可以解开这个密文

下面是Java实现,RSA算法由JAVA标准库提供支持。

首先准备Human类:

  • 两个Human实例代表小红和小明,分别有公钥和私钥的成员变量;
  • 通过构造方法来生成各自的公私钥对。
  • 实现了加密方法encrypt()和解密方法decrypt()。
// 用户类
class Human{
    // 姓名
    String name;

    // 私钥:
    PrivateKey privatekey;

    // 公钥:
    PublicKey publickey;

    // 构造方法
    public Human(String name) throws GeneralSecurityException{
        // 初始化姓名
        this.name= name;
        // 生成公钥/私钥对:
        KeyPairGenerator kpGen= KeyPairGenerator.getInstance("RSA");
        kpGen.initialize(1024);
        KeyPair kp = kpGen.generateKeyPair();

        this.privatekey= kp.getPrivate();
        this.publickey= kp.getPublic();
    }

    // 获取私钥
    public PrivateKey getPrivateKey(){
        return this.privatekey;
    }
    // 获取公钥
    public PublicKey getPublicKey(){
        return this.publickey;
    }

    // 用公钥加密
    public byte[] encrypt(byte[] message,PublicKey publickey) throws GeneralSecurityException {
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, publickey); // 使用公钥进行初始化
        return cipher.doFinal(message);
    }

    // 用私钥解密:
    public byte[] decrypt(byte[] input) throws GeneralSecurityException {
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE, this.privatekey); // 使用私钥进行初始化
        return cipher.doFinal(input);
    }
}

测试类:

分别获取小红的公钥和私钥进行加密解密操作。

// RSA
public class Main {
    public static void main(String[] args) throws Exception {
    // 明文:
    byte[] plain = "Hello, encrypt use RSA".getBytes("UTF-8");

    // 创建公钥/私钥对
    Human hong = new Human("小红");
    Human ming = new Human("小明");

    // 小明使用小红的公钥进行加密
    // 1.获取小红的公钥
    PublicKey hongPublicKey = hong.getPublicKey();
    System.out.println(String.format("小红的public key(公钥): %x", new BigInteger(1,                                                 hongPublicKey.getEncoded())));

    // 2.使用公钥加密
    byte[] encrypted = ming.encrypt(plain,hongPublicKey);
    System.out.println(String.format("encrypted(加密): %x", new BigInteger(1, encrypted)));

    // 小红使用自己的私钥解密:
    // 1.获取小红的私钥,并输出
    PrivateKey hongPrivateKey = hong.getPrivateKey();
    System.out.println(String.format("小红的private key(私钥): %x", new BigInteger(1, hongPrivateKey.getEncoded())));

    // 2.使用私钥解密
    byte[] decrypted = hong.decrypt(encrypted);
    System.out.println("decrypted(解密): " + new String(decrypted, "UTF-8"));
    }
}

RSA的公钥和私钥都可以通过getEncoded()方法获得以byte[]表示的二进制数据,并根据需要保存到文件中。要从byte[]数组恢复公钥或私钥,可以这么写:

  1. 先根据"RSA"算法创建KeyFactory实例;
  2. 再将公钥的字节数组包装成 X509EncodedKeySpec 对象;
  3. 将私钥的字节数组包装成 PKCS8EncodedKeySpec 对象;
  4. 最后使用KeyFactory实例分别生成PublicKey类型的对象和PrivateKey类型的对象;

这样就完成了从字节数组恢复为公钥私钥对象。

byte[] pkData = ...
byte[] skData = ...
KeyFactory kf = KeyFactory.getInstance("RSA");

// 恢复公钥:
X509EncodedKeySpec pkSpec = new X509EncodedKeySpec(pkData);
PublicKey pk = kf.generatePublic(pkSpec);

// 恢复私钥:
PKCS8EncodedKeySpec skSpec = new PKCS8EncodedKeySpec(skData);
PrivateKey sk = kf.generatePrivate(skSpec);

总结

  • 和密钥交换算法不同,非对称加密算法只是单向传输,且只传输公钥;
  • 以RSA算法为例,它的密钥有256/512/1024/2048/4096等不同的长度。长度越长,密码强度越大,当然计算速度也越慢;
  • 非对称加密就是加密和解密使用的不是相同的密钥,只有同一个公钥-私钥对才能正常加解密; 
  • 将字节数组恢复为公钥私钥对象,需要KeyFactory来生成;

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值