【密码学必知】RSA算法

1,264 阅读2分钟

RSA

1. 简述

RSA(Rivest–Shamir–Adleman), 非对称密码算法,RSA加密算法是美国麻省理工学院的三位科学家 Rivest、Shamir、Adleman于1978年提出的, 简称RSA公钥密码系统。

理论基础: RSA算法的理论基础是数论的欧拉函数

安全性: 对极大整数做因数分解的难度决定了 RSA 算法的可靠性。密钥越长,它就越难破解。截至 2022 年,已知被破解的最大 RSA 密钥是 829 位的 RSA-250。自 2015 年以来,NIST 建议 RSA 密钥长度至少为 2048 位。

用途: 数字签名、加密算法。作为加密算法使用的 RSA 会随着密钥长度增加,性能会急剧下降。

2. 数论基础

质数: 也称素数,是指在大于1的自然数中,除了1和它本身以外不再有其他因数的自然数。

互质: 公约数只有1的两个整数,叫做互质整数。公约数只有1的两个自然数,叫做互质自然数。

整数分解: 也称质因数分解,是将一个正整数写成几个因数的乘积。因数分解的关键是寻找因子(约数),而完整的因子列表可以根据约数分解推导出,将幂从零不断增加直到等于这个数。

欧拉函数: 在数论,对正整数n,欧拉函数是小于等于n的正整数中与n互质的数的数目。

欧拉定理

3. 公私钥生成过程

Steps:

  1. Choose two different large random prime numbers say “p” and “q”.
  2. Calculate n = p * q. Since “n” is the modulus for the public key and the private keys
  3. Calculate the totient: Ø (n) = (p - 1)(q - 1)
  4. Choose an integer “e” such that 1 < e < Ø (n) and “e” is co-prime to Ø (n) i.e. “e” and Ø (n) share no factors other than 1.
  5. Find out decryption key “d” such that e * d = 1 mod (p - 1) (q - 1).
  6. Encrypt the message “m” using encryption key e, c = m^e mod n.
  7. Decrypt the message “m” using decryption key d, m = c^d mod n.

(加密消息、解密消息、签名消息等,网上有很多资料)

Java 中的 Key Pair

jdk java.security 包下的 KeyPairGenerator 类可用来生成 RSA 算法的公私钥

public static void main(String[] args) throws NoSuchAlgorithmException {
    KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");
    generator.initialize(2048);
    KeyPair keyPair = generator.generateKeyPair();

    RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
    RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
    
    String publicKeyString = Base64.getEncoder().encodeToString(publicKey.getEncoded());
    String privateKeyString = Base64.getEncoder().encodeToString(privateKey.getEncoded());
    System.out.println(publicKeyString);
    System.out.println(privateKeyString);
}

SSH Key Pair

1. 命令行生成密钥对

  • 生成公私钥:

    ssh-keygen -t rsa

    image.png 公钥:my_key.pub,私钥: my_key

  • 校验公私钥是否匹配:

    ssh-keygen -l -f my_key

    ssh-keygen -l -f my_key.pub

    如果二者生成的字符串一致,则说明公私钥是匹配的。

2. Java 生成密钥对

使用 jsch 生成 RSA 公钥、指纹、密钥

public static void main(String[] args) throws JSchException {
    String comment = "gen rsa key pair";
    KeyPair keyPair = KeyPair.genKeyPair(new JSch(), KeyPair.RSA);

    ByteArrayOutputStream publicKeyOut = new ByteArrayOutputStream();
    ByteArrayOutputStream privateKeyOut = new ByteArrayOutputStream();
    keyPair.writePublicKey(publicKeyOut, comment);
    keyPair.writePrivateKey(privateKeyOut);

    String publicKey = publicKeyOut.toString();
    String fingerPrint = keyPair.getFingerPrint();
    String privateKey = privateKeyOut.toString();

    System.out.println(publicKey);
    System.out.println(fingerPrint);
    System.out.println(privateKey);
}

参考:

欧拉函数

RSA加密算法

Elaborate the steps of key generation using RSA algorithm.

Java Code Examples for java.security.KeyPairGenerator