帮助文档:Forge的Github链接
步骤:
pip install
import forge from 'node-forge'
例如指定:RSA/ECB/OAEPWithSHA-256AndMGF1Padding
- **RSA**: 这表示使用 RSA 加密算法。
- **ECB**: 这表示使用电子密码本 (Electronic Codebook) 模式进行加密。ECB 模式是一种基本的块加密模式,将明文分成固定大小的块,然后分别用密钥加密。
- **OAEPWithSHA-256AndMGF1Padding**: 这表示使用 OAEP (Optimal Asymmetric Encryption Padding) 填充方案进行填充,并指定了哈希算法 SHA-256 和 MGF1 (Mask Generation Function 1) 作为填充方案的一部分。OAEP 是一种针对 RSA 加密算法设计的填充方案,旨在提供更好的安全性和随机性,以及防止对明文的长度或结构进行分析。
综合起来,"RSA/ECB/OAEPWithSHA-256AndMGF1Padding" 表示使用 RSA 加密算法,采用 ECB 模式进行加密,并使用 OAEP 填充方案,其中哈希算法为 SHA-256,MGF1 作为填充方案的一部分。
注释还贴心指定了Java参数是什么样子,你可一观察一下不同位置设置的对应关系推到一下你的参数设置;
```ts
export const $encryptMessage = (plaintext: any, publicKeyString: any) => {
console.log("@5")
// 生成一个 2048 位的 RSA 密钥对
var keypair = forge.pki.rsa.generateKeyPair({ bits: 2048, e: 0x10001 });
// 获取生成的公钥和私钥
const publicKey = keypair.publicKey;
const privateKey = keypair.privateKey;
// 将待加密的字符串转换为字节数组
var dataBytes = forge.util.encodeUtf8(plaintext);
// 加密数据
var encryptedBytes = publicKey.encrypt(dataBytes, 'RSA-OAEP', {
md: forge.md.sha256.create(),
mgf1: {
md: forge.md.sha1.create()
}
});
// 将加密后的字节数组转换为 Base64 编码的字符串
var encryptedBase64 = forge.util.encode64(encryptedBytes);
console.log("加密后数据", encryptedBase64);
// 使用私钥解密数据
var receivedEncryptedBytes = forge.util.decode64(encryptedBase64);
var decryptedBytes = privateKey.decrypt(receivedEncryptedBytes, 'RSA-OAEP', {
md: forge.md.sha256.create()
});
// 将解密后的字节数组转换为字符串
var decryptedPlaintext = forge.util.decodeUtf8(decryptedBytes);
console.log("Original plaintext:", plaintext);
console.log("Decrypted plaintext:", decryptedPlaintext);
```
------
注意一下钥匙的格式为PEM格式:PEM 格式的数据通常以 `-----BEGIN` 开头,以 `-----END` 结尾,之间是经过 Base64 编码的数据。这种格式常用于存储和传输各种类型的密钥、证书等信息。
```vbnet
公钥:
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAjgRrqVP+D+CZCHr++8Bs
e+mQ/Wjt0lW9zkp6bghQAfg3wR5XmYYOFWs/0lqWYgCYiwSX+iFQap6+dtkuE7jP
HjU6d9I0hXXSoUIMaxo2WA3IfXI45n2tRHPInCTgCoPNpHtycfMaaboBQ99altqd
TvOylEiEgdZZ4v8Elksi9F7suvx7cCy2yJFF5rK0PtVEUMYe31EFWuKDlMyUvXcn
8aU/81v2Z+cxyIph9WL4kVFo8qV3R+eFilbm/gPFSl5YXra16aUxwWEFvZVsNoK9
zHNA0K4XjzF1eGk99M28B65gM5FIdKQ6SF3CdKk9C1mYCAVX6WeOC1i+5XNGJRry
nwIDAQAB
-----END PUBLIC KEY-----
私钥:
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA3F0fXoAC5elYAYU27JQ61iD/GKc+Km3LHV4J+7JNNfX7JzoY
2fYgbVc+JJESmISs8O2z6LsjSQQ6VG2ukYcEZwIiq++HebZOHimIBLLaKry7NmQ3
BJpJ8Y70jY2xqOQ29S+Z1Z+1HKnmUl44xJ5UG1C3ZoCYvh/PzPqC3Mfk2mT/rV2m
UCj9g83eazw/e0ONi5DqcXyKq0EQW0rE4rZVHLuw4pNgRXwWLO5qSgN+4YhOfNpH
...此处省略私钥长一点....
-----END RSA PRIVATE KEY-----
```
--------
如果你的公钥和私钥只有中间部分,就需要转换
```ts
function convertToPublicPem(publicKeyBase64: string): string {
const lines = [];
lines.push('-----BEGIN PUBLIC KEY-----');
for (let i = 0; i < publicKeyBase64.length; i += 64) {
lines.push(publicKeyBase64.slice(i, i + 64));
}
lines.push('-----END PUBLIC KEY-----');
return lines.join('\n');
}
function convertToPrivatePem(privateKeyBase64: string): string {
const lines = [];
lines.push('-----BEGIN PRIVATE KEY-----');
for (let i = 0; i < privateKeyBase64.length; i += 64) {
lines.push(privateKeyBase64.slice(i, i + 64));
}
lines.push('-----END PRIVATE KEY-----');
return lines.join('\n');
}
```
(通常加密在前端,解密在后端,为了你好定位问题,提供加密和解密,代码写错了是无法解密的)
```ts
console.log("@5")
// 生成一个 2048 位的 RSA 密钥对
// var keypair = forge.pki.rsa.generateKeyPair({ bits: 2048, e: 0x10001 });
// 获取生成的公钥和私钥
// const publicKey = keypair.publicKey;
// const privateKey = keypair.privateKey;
// 从 PEM 格式的字符串加载公钥和私钥
console.log("@4")
var publicKeyString1 = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAjgRrqVP+D+CZCHr++8Bse+mQ/Wjt0lW9zkp6bghQAfg3wR5XmYYOFWs/0lqWYgCYiwSX+iFQap6+dtkuE7jPHjU6d9I0hXXSoUIMaxo2WA3IfXI45n2tRHPInCTgCoPNpHtycfMaaboBQ99altqdTvOylEiEgdZZ4v8Elksi9F7suvx7cCy2yJFF5rK0PtVEUMYe31EFWuKDlMyUvXcn8aU/81v2Z+cxyIph9WL4kVFo8qV3R+eFilbm/gPFSl5YXra16aUxwWEFvZVsNoK9zHNA0K4XjzF1eGk99M28B65gM5FIdKQ6SF3CdKk9C1mYCAVX6WeOC1i+5XNGJRrynwIDAQAB";
var privateKeyString ="MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCOBGupU/4P4JkIev77wGx76ZD9aO3SVb3OSnpuCFAB+DfBHleZhg4Vaz/SWpZiAJiLBJf6IVBqnr522S4TuM8eNTp30jSFddKhQgxrGjZYDch9cjjmfa1Ec8icJOAKg82ke3Jx8xppugFD31qW2p1O87KUSISB1lni/wSWSyL0Xuy6/HtwLLbIkUXmsrQ+1URQxh7fUQVa4oOUzJS9dyfxpT/zW/Zn5zHIimH1YviRUWjypXdH54WKVub+A8VKXlhetrXppTHBYQW9lWw2gr3Mc0DQrhePMXV4aT30zbwHrmAzkUh0pDpIXcJ0qT0LWZgIBVfpZ44LWL7lc0YlGvKfAgMBAAECggEADZIZkZwvlmfRZ9CNBhSMqUiX7Mc2lpdP5GMUkOglcRK9jSwvlcGMHfraJek3HpVM/lfJiALf8thJfgTh1MufqxTOCf4hu7EXGAa+NgvSrpZelrIwAsJ2qKhhvp39dLPEllefh4kB+KFoForE1s58IrvB0E6fruKDQ2A4GX6DkBNPlAykT7a8KrO1dqBJe8jtjf4CiOCR6Y6j0hq4tz12dZXO1FY5/gFcq7Oj5j4k1iXAPGkVLS7cZYUQhfsXfiP75q/y/hyUbYsVDW6xBWidfyc8cCNRo8fDnC8MDLa0H5TRAe+mWkYKX6M1ZSpo3E2LDTizVr7GaMBwgZ9yxmvA1QKBgQC2F1ymUQexGXecYBsHlesH0ulOlU90XptH0fMDXxR+Z7ae5gK4QAZePRZNofatOyyQGQ1+u21d9mOLv7Wm/HcTofVYODQTEBheFlbzpYZ5ciLUfuYXNmRgQlnZFkP/x3xA+lVhuCEyE87liQ+iH3FCFHh9X2mAoAim7hN8J5SpBQKBgQDHqRKVW4UXSN5sQYn0j8yGPUB5Q5BCrZCn38T+NWXNPnXBcTY80VhOZtWR41+9zdowDp7AzOZV6xWMn1hrt9xaMP+tcbB1iIcc6XTxcHDVzppt8HXIqqnpXxM041Sz1rEGW/lcNADZabJIWn2AE4XDiP2iX+IV3AU27dS5tKhuUwKBgCgX0MCWCtmFv/5gctMiwVNBrzksSwhWZF5V7eoKH1sNvvoRrvuerUhGrwh85vGRm+hGe+AxqI0N2TFGDtsrr5RVDs5T4bNo0dS1moOfKJLI/L5JCqSFx2gic+IGswY4iDVOaUpQ3o5GKkIEAbsyrR9dnoIMZhB6LC2FMikeFe95AoGBAMa5o8OBOjD42FmLyhHfZsReBuQruVSEiKxubxZOc6sbdf05/6/89hXjCMOSOmMilv6qLpzb1I7D08kJeOqOMAadKn6p3+a8Iy9Ftp3xOn20i8TNR46ZP1EGzokfk9kD4WLg/IsnP4kmSMr3Nl7aD5OVsE2DffYf7hjEE61bASH9AoGAFGDQg/ym2KwNqpt1xOVdpXpVTrkwKCqMiugcMEnFo3YaiODGH8wPqGjbkrbF+xlHZZK2tmcPpSzo2AidgSUAsgna6mYpSlLb9mfQTzMufMk7H27dUwjXKfhZdZkOnHaUy07ElokbjItGv8zedJBrzzz8hQdfy6id+vLJda0OFFI=";
console.log("@3")
const publicKey = forge.pki.publicKeyFromPem(convertToPublicPem(publicKeyString1));
console.log("@2")
const privateKey = forge.pki.privateKeyFromPem(convertToPrivatePem(privateKeyString));
console.log("@1")
// 将待加密的字符串转换为字节数组
var dataBytes = forge.util.encodeUtf8(plaintext);
// 加密数据
var encryptedBytes = publicKey.encrypt(dataBytes, 'RSA-OAEP', {
md: forge.md.sha256.create(),
mgf1: {
md: forge.md.sha1.create()
}
});
// 将加密后的字节数组转换为 Base64 编码的字符串
var encryptedBase64 = forge.util.encode64(encryptedBytes);
console.log("加密后数据", encryptedBase64);
// 使用私钥解密数据
var receivedEncryptedBytes = forge.util.decode64(encryptedBase64);
var decryptedBytes = privateKey.decrypt(receivedEncryptedBytes, 'RSA-OAEP', {
md: forge.md.sha256.create()
});
// 将解密后的字节数组转换为字符串
var decryptedPlaintext = forge.util.decodeUtf8(decryptedBytes);
console.log("Original plaintext:", plaintext);
console.log("Decrypted plaintext:", decryptedPlaintext);
```
```
//获取公钥
export const $getPublicKey = async ()=>{
const {data} = await $post(UserApi.getPublicKey,"");
return data
}
function convertToPublicPem(publicKeyBase64: string): string {
const lines = [];
lines.push('-----BEGIN PUBLIC KEY-----');
for (let i = 0; i < publicKeyBase64.length; i += 64) {
lines.push(publicKeyBase64.slice(i, i + 64));
}
lines.push('-----END PUBLIC KEY-----');
return lines.join('\n');
}
// 加密消息
export const $encryptMessage = (plaintext: any, publicKeyString: any) => {
const publicKey = forge.pki.publicKeyFromPem(convertToPublicPem(publicKeyString));
// 将待加密的字符串转换为字节数组
var dataBytes = forge.util.encodeUtf8(plaintext);
// 加密数据
var encryptedBytes = publicKey.encrypt(dataBytes, 'RSA-OAEP', {
md: forge.md.sha256.create(),
mgf1: {
md: forge.md.sha1.create()
}
});
// 将加密后的字节数组转换为 Base64 编码的字符串
var encryptedBase64 = forge.util.encode64(encryptedBytes);
console.log("加密后数据", encryptedBase64);
return encryptedBase64;
}
export const $login = async (params:any)=>{
try{
const publicKey = await $getPublicKey()
params.password = $encryptMessage(params.password, publicKey)
xxxx发送请求xxxx
}catch (error) {
console.error('登录时发生错误:', error);
throw error; // 将错误继续向外抛出
}
}
```
if (publicKey == null && privateKey == null) {
try {
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
keyGen.initialize(2048);
KeyPair pair = keyGen.generateKeyPair();
// 保存公钥和私钥
publicKey = pair.getPublic();
privateKey = pair.getPrivate();
// 输出公钥和私钥的Base64编码值
log.info("RSA密钥生成成功: 公钥={}, 私钥={}",
Base64.getEncoder().encodeToString(publicKey.getEncoded()),
Base64.getEncoder().encodeToString(privateKey.getEncoded()));
} catch (Exception e) {
log.error("初始化RSA密钥失败:", e.getMessage());