RSA非对称加密算法

发布于:2024-10-17 ⋅ 阅读:(145) ⋅ 点赞:(0)

  RSA是一种公钥密码算法,它利用两个密钥——公钥和私钥——来加密和解密信息。公钥可以公开给任何人,而私钥必须保密。

核心原理

生成密钥对

选择两个大质数p和q

  • pq是随机选择的不同大质数
  • n=p×q,这是用来生成公钥和私钥的基础。

计算ϕ(n)

  • ϕ(n)=(p−1)×(q−1),这个数用来确定加密和解密的关系。

选择公钥指数 e

  • 选择一个整数 e 使得 1<e<ϕ(n),并且 e ϕ(n) 互质,即 gcd(e,ϕ(n))=1)
  • 通常选择的 e 值是 3、17 或 65537,因为这些值可以使得加密过程更快。

计算私钥 d

  • d 是 e 关于 ϕ(n) 的模反元素,即满足 e×d≡1(modϕ(n))。
  • 通过扩展欧几里得算法可以求出 d。

生成密钥对

  • 公钥:(e,n)
  • 私钥:(d,n)

加密过程

加密
使用公钥 (e,n) 将明文 M 加密成密文 C。
在这里插入图片描述
明文M必须是一个小于n的整数。

解密
使用私钥(d,n)将密文C解密回明文M

在这里插入图片描述

Python调用RSA

生成RSA密钥对

from Crypto.PublicKey import RSA

# 生成2048位的RSA密钥对
key = RSA.generate(2048)

# 获取私钥和公钥
private_key = key.export_key()
public_key = key.publickey().export_key()

print("Private Key:", private_key.decode())
print("Public Key:", public_key.decode())

密钥

Private Key: -----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAnxpYCbb4dyt9qalpaX7n9GWXSQztcGMJgO5LAlwyyEic06wg
02/B0DsV0WXjVHHQFtpXd2U6PxE6gcHSJydH91gSbGTfc21owIrqd/j5I8xgYVjp
MNvcwwaubujEv5O0aqqywPYhFkShRV3J7kXdcj30FpKtAz4fnj9lnpxicGCIPWJf
V96VSe1Q61tbXS1lhN8SC+NiB+CfEpsltAVmlzaYxfDjnI8Ns0ZvqvM+FRBw/6f0
34MnEl8Q0CWHqz/C7B6wHlx3pfrrBgfjJLMxDQNobJj64r1FRWTCZAKzbMUpzuMY
MZ6sVJL7DxXbZqzz3rywJ9X8/hjwwCHriSfMrQIDAQABAoIBAAMToVbewO3yW1sS
ju/z/Pb5l/QDr1EYY9tTFa7qqti7VBJhJmla+eaASKsPS1bGCf4ceXXc8UQS8zdb
JiiNAT6ZPLyiiWepWqM5NyYxca/tiIJEE+Or/MLmDYLQ4YJ1kBbtTMj1JC1Sum5Q
TVKxlddbDK37EXlvPsadTJEao79Z4WNxKM4YpxMe7rfOx/LEdP5qnSsHiWnYjuDv
OeHZEbRf01HKm2Cxjhs2LSXqwUSUCk+Kz6sj2NA+YwrzdcNLEbSJ8MSfrpehorqo
9CtP47wB4eL3Loeb2abfkiBD3SM8jlHLKJSCrj8zPgKnDvwAJ429/2uz8LStTTh3
UVYMggkCgYEAwegyaeDp/Otq/pReuWvOgA36y42lt5ve8tW4QjOsQxbEfypbLcyI
LirgcfZkWgJ+TJCMjlgPLdAhyAjz9AEwv4m6XVfBfHlhjKmUWUspovFi0Fgdu7Y7
n6LAl9InL24iABPPolSSEWTKiCBX8KVxUHygJ9RQ9EnLoYgAXsrKzlcCgYEA0g0H
x0o4omFV6hfuANbCdnU4ZA6YV1Kx8Fi9sMjgKhP/9xNzzruA/QEi/UhOangdNRUO
5r2vxlYyYsSIj73SNjuLhDgJs0RBFu2vbpfxcMWEvViKkOQdM21V/inDQv+B2wPm
rQI7UOT6b1Fe6op2k8hp3X7gY7+cyHcuP5LDUpsCgYEAuSPorqsu/mwQto4Xe1bx
zdaLNTtDlPHgh1+EFMGdoljkuL5KXIpDJEGQF3+4BTEIQjZp3ac6pvVoq8PQmZNh
ZiAsrt8RQLXsbA+mMzPOx2NOg7r+eLHgb+VHmi3veBvhns1LnKS+6pifwCWRkZWF
geHcUOspeHXVVZ+zKs7ZoPUCgYBJwH+BrwLRqQGEj2Bm9QEUnLXvE9zTlFqb/Fym
TPHAdINEWpUn+lgg/ZwueIvoAEKpF7rCs8mbBzrryPv2FH1Rw3iKNS7avdVo2o3l
c/43TXL9FLCajS3fl71A36MKzDHpF6aQCp+PGMcB/P0ptvJJk23wcpMREv9Wt9oK
QlrIjwKBgF8DUVHLoPVpByheo+rxwylH9KmcwOfvQHhjj76rECA67VzL06/5D4w1
WPYUAu4ssAPc6r3apBk55bwc+qofKmb7eWr/MyPvfuReSzranmvHjEQl6B0HxX08
RHSt8oSDLAm7pxsio7pJM84zCv6AcUVKlq5KULBgsxfKyIdBlNq7
-----END RSA PRIVATE KEY-----
Public Key: -----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnxpYCbb4dyt9qalpaX7n
9GWXSQztcGMJgO5LAlwyyEic06wg02/B0DsV0WXjVHHQFtpXd2U6PxE6gcHSJydH
91gSbGTfc21owIrqd/j5I8xgYVjpMNvcwwaubujEv5O0aqqywPYhFkShRV3J7kXd
cj30FpKtAz4fnj9lnpxicGCIPWJfV96VSe1Q61tbXS1lhN8SC+NiB+CfEpsltAVm
lzaYxfDjnI8Ns0ZvqvM+FRBw/6f034MnEl8Q0CWHqz/C7B6wHlx3pfrrBgfjJLMx
DQNobJj64r1FRWTCZAKzbMUpzuMYMZ6sVJL7DxXbZqzz3rywJ9X8/hjwwCHriSfM
rQIDAQAB
-----END PUBLIC KEY-----

保存密钥到文件

# 将私钥和公钥保存到文件
with open('private.pem', 'wb') as f:
    f.write(private_key)

with open('public.pem', 'wb') as f:
    f.write(public_key)

加密和解密

from Crypto.PublicKey import RSA

# 生成2048位的RSA密钥对
key = RSA.generate(2048)

# 获取私钥和公钥
private_key = key.export_key()
public_key = key.publickey().export_key()

# 将私钥和公钥保存到文件
with open('private.pem', 'wb') as f:
    f.write(private_key)

with open('public.pem', 'wb') as f:
    f.write(public_key)


from Crypto.Cipher import PKCS1_OAEP
from Crypto.PublicKey import RSA

with open('public.pem','rb') as f:
    public_key = RSA.import_key(f.read())

with open('private.pem','rb') as f:
    private_key = RSA.import_key(f.read())

# 加密
message = "Bileton".encode("utf-8")
cipher_rsa = PKCS1_OAEP.new(public_key)
encrypted_message = cipher_rsa.encrypt(message).hex()
print(encrypted_message) # 每次生成的密文都不一样

# 解密
original_encrypted_message = bytes.fromhex(encrypted_message)
cipher_rsa_decrypt = PKCS1_OAEP.new(private_key)
decrypt_message = cipher_rsa_decrypt.decrypt(original_encrypted_message).decode("utf-8")
print(decrypt_message)

输出

800868d5564180ae3dbb88066622bb0f094dea6fc61320cdbe4f10a216f9edbf2e148de0116afbfff59f923b6309fee1fbfdc5b0de29d27d7c65b1367d4a8dd2b70ee2e7bb759f2a6f0bc14a815c61c44281cc89262c4de479dc1ad68e95e9245496c4422bd6af0104c2539cffecde13756258af51c33203651951a469a62ec7dd998a6a4f0179f9730bd9dcc916f65162382a0e2b19002690a0c00e97b1fed941e9f6ddee3f37a4c3a73e82ed86be2448d6a44a17a312436629d27fbb21f3495996ca2ee7d8b97f35c0b525cac9c1658b68b3d4e6a776b541853b7a6813ce9a762d42194934ea04a2e002093a5bbe002540a1b5341e006d73857804a82d292f
Bileton

Java调用RSA

生成RSA密钥对

import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;

public class RSAExample {
    public static void main(String[] args) throws Exception {
        // 生成RSA密钥对
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
        keyPairGenerator.initialize(2048); // 设置密钥大小为2048位
        KeyPair keyPair = keyPairGenerator.generateKeyPair();
        
        PublicKey publicKey = keyPair.getPublic();
        PrivateKey privateKey = keyPair.getPrivate();
        
        System.out.println("Public Key: " + publicKey);
        System.out.println("Private Key: " + privateKey);
    }
}

加密和解密

KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(2048);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
PublicKey publicKey = keyPair.getPublic();
PrivateKey privateKey = keyPair.getPrivate();

String message = "Bileton";
Cipher encrypter = Cipher.getInstance("RSA/ECB/PKCS1Padding");
encrypter.init(Cipher.ENCRYPT_MODE,publicKey);
encrypter.update(message.getBytes());
byte[] encryptedata = encrypter.doFinal();
String encodeencryptedata = Base64.getEncoder().encodeToString(encryptedata);
System.out.println(encodeencryptedata);


Cipher decrypter = Cipher.getInstance("RSA/ECB/PKCS1Padding");
decrypter.init(Cipher.DECRYPT_MODE,privateKey);
decrypter.update(Base64.getDecoder().decode(encodeencryptedata));
byte[] decryptedata = decrypter.doFinal();
String encodedecryptedata = new String(decryptedata);
System.out.println(encodedecryptedata); # Bileton

Android Studio

KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
KeyPair keyPair = keyPairGenerator.generateKeyPair();
PublicKey publicKey = keyPair.getPublic();
PrivateKey privateKey = keyPair.getPrivate();

String message = "Bileton";
Cipher encryptoCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
encryptoCipher.init(Cipher.ENCRYPT_MODE,publicKey);
encryptoCipher.update(message.getBytes());
byte[] encryptedata = encryptoCipher.doFinal();

Cipher decryptCipher= Cipher.getInstance("RSA/ECB/PKCS1Padding");
decryptCipher.init(Cipher.DECRYPT_MODE,privateKey);
decryptCipher.update(encryptedata);
byte[] decryptedata = decryptCipher.doFinal();
String originaldata = new String(decryptedata);
Toast.makeText(MainActivity.this,originaldata,Toast.LENGTH_SHORT).show();

在这里插入图片描述


网站公告

今日签到

点亮在社区的每一天
去签到