@yoooloo42/beat 1.0.19 → 1.0.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/libs/Base64.js +121 -0
- package/src/libs/Base64.js.test.png +0 -0
- package/src/libs/crypto/AES.js +53 -42
- package/src/libs/crypto/RSA.js +68 -16
package/package.json
CHANGED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import https from 'https';
|
|
4
|
+
import http from 'http'; // 也可能需要处理 http 链接
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* 从本地文件路径获取文件的 Base64 编码。
|
|
8
|
+
* @param {string} filePath - 本地文件的绝对或相对路径。
|
|
9
|
+
* @returns {Promise<string>} - 文件的 Base64 编码字符串。
|
|
10
|
+
*/
|
|
11
|
+
function getBase64FromLocalFile(filePath) {
|
|
12
|
+
return new Promise((resolve, reject) => {
|
|
13
|
+
// 确保路径是绝对路径
|
|
14
|
+
const absolutePath = path.resolve(filePath);
|
|
15
|
+
|
|
16
|
+
// 使用 { encoding: 'base64' } 直接读取为 Base64 字符串
|
|
17
|
+
fs.readFile(absolutePath, { encoding: 'base64' }, (err, data) => {
|
|
18
|
+
if (err) {
|
|
19
|
+
console.error(`[本地文件错误] 读取本地文件失败: ${err.message}`);
|
|
20
|
+
return reject(err);
|
|
21
|
+
}
|
|
22
|
+
resolve(data);
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* 从远程文件 URL 获取文件的 Base64 编码,支持自动重定向跟随 (3xx 状态码)。
|
|
29
|
+
* @param {string} fileUrl - 远程文件的完整 URL。
|
|
30
|
+
* @param {number} [redirects=5] - 最大重定向次数限制。
|
|
31
|
+
* @returns {Promise<string>} - 文件的 Base64 编码字符串。
|
|
32
|
+
*/
|
|
33
|
+
function getBase64FromURL(fileUrl, redirects = 5) {
|
|
34
|
+
if (redirects === 0) {
|
|
35
|
+
return Promise.reject(new Error(`[远程文件错误] 重定向次数过多 (${fileUrl})`));
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// 根据 URL 协议选择合适的模块
|
|
39
|
+
const client = fileUrl.startsWith('https') ? https : http;
|
|
40
|
+
|
|
41
|
+
return new Promise((resolve, reject) => {
|
|
42
|
+
client.get(fileUrl, (res) => {
|
|
43
|
+
const statusCode = res.statusCode;
|
|
44
|
+
|
|
45
|
+
// --- 处理重定向 (3xx 状态码) ---
|
|
46
|
+
if (statusCode >= 300 && statusCode < 400 && res.headers.location) {
|
|
47
|
+
const newUrl = res.headers.location;
|
|
48
|
+
console.log(`[重定向] 遇到状态码 ${statusCode},重定向至: ${newUrl}`);
|
|
49
|
+
// 递归调用自身,跟随重定向
|
|
50
|
+
return getBase64FromURL(newUrl, redirects - 1)
|
|
51
|
+
.then(resolve)
|
|
52
|
+
.catch(reject);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// --- 处理请求失败 (4xx, 5xx) ---
|
|
56
|
+
if (statusCode < 200 || statusCode >= 400) {
|
|
57
|
+
return reject(new Error(`[远程文件错误] 请求失败,状态码: ${statusCode} (${fileUrl})`));
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// --- 成功获取 (2xx) ---
|
|
61
|
+
const chunks = [];
|
|
62
|
+
res.on('data', (chunk) => {
|
|
63
|
+
chunks.push(chunk);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
res.on('end', () => {
|
|
67
|
+
try {
|
|
68
|
+
// 合并所有 Buffer 块并转换为 Base64 字符串
|
|
69
|
+
const buffer = Buffer.concat(chunks);
|
|
70
|
+
const base64String = buffer.toString('base64');
|
|
71
|
+
resolve(base64String);
|
|
72
|
+
} catch (e) {
|
|
73
|
+
reject(new Error(`[远程文件错误] 处理远程文件数据失败: ${e.message}`));
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
}).on('error', (err) => {
|
|
78
|
+
console.error(`[远程文件错误] 远程请求连接错误: ${err.message}`);
|
|
79
|
+
reject(err);
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/*
|
|
85
|
+
// ------------------------------------
|
|
86
|
+
// 示例执行
|
|
87
|
+
// ------------------------------------
|
|
88
|
+
|
|
89
|
+
// 1. 本地文件示例(请确保 'test.bmp' 存在于同一目录下)
|
|
90
|
+
// 注意:如果文件不存在,会捕获到错误。
|
|
91
|
+
getBase64FromLocalFile('Base64.js.test.png')
|
|
92
|
+
.then(base64String => {
|
|
93
|
+
console.log('\n--- 本地文件结果 ---');
|
|
94
|
+
console.log(`本地文件的 Base64 编码长度: ${base64String.length}`);
|
|
95
|
+
console.log(`本地文件的 Base64 编码 (前50字符): ${base64String.substring(0, 50)}...`);
|
|
96
|
+
})
|
|
97
|
+
.catch(error => {
|
|
98
|
+
// 捕获本地文件不存在或权限不足的错误
|
|
99
|
+
console.error('\n--- 本地文件错误 ---');
|
|
100
|
+
console.error('获取本地文件 Base64 失败:', error.message);
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
// 2. 远程 URL 示例(使用支持重定向的函数)
|
|
104
|
+
const remoteUrl = 'https://picsum.photos/200/300'; // 这个 URL 会导致 302 重定向
|
|
105
|
+
getBase64FromURL(remoteUrl)
|
|
106
|
+
.then(base64String => {
|
|
107
|
+
console.log('\n--- 远程文件结果 ---');
|
|
108
|
+
console.log(`远程文件的 Base64 编码长度: ${base64String.length}`);
|
|
109
|
+
console.log(`远程文件的 Base64 编码 (前50字符): ${base64String.substring(0, 50)}...`);
|
|
110
|
+
})
|
|
111
|
+
.catch(error => {
|
|
112
|
+
// 捕获请求失败或重定向超时的错误
|
|
113
|
+
console.error('\n--- 远程文件错误 ---');
|
|
114
|
+
console.error('获取远程文件 Base64 失败:', error.message);
|
|
115
|
+
});
|
|
116
|
+
*/
|
|
117
|
+
|
|
118
|
+
export default {
|
|
119
|
+
getBase64FromLocalFile,
|
|
120
|
+
getBase64FromURL
|
|
121
|
+
}
|
|
Binary file
|
package/src/libs/crypto/AES.js
CHANGED
|
@@ -4,74 +4,66 @@ import crypto from 'crypto';
|
|
|
4
4
|
const ALGORITHM = 'aes-128-cbc'; // 算法:AES-128-CBC
|
|
5
5
|
const IV_LENGTH = 16; // IV 长度:16 字节 (128 位)
|
|
6
6
|
const KEY_LENGTH = 16; // 密钥长度:16 字节 (128 位)
|
|
7
|
-
const
|
|
8
|
-
const
|
|
7
|
+
const PLAINTEXT_ENCODING = 'utf8'; // 明文输入编码
|
|
8
|
+
const CIPHER_OUTPUT_FORMAT = 'base64';// 密文输出格式 (Base64)
|
|
9
|
+
const KEY_IV_FORMAT = 'base64'; // 密钥和 IV 的传输/存储格式 (Base64)
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
* 🔑 生成安全随机的 AES 密钥和 IV。
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* @returns {Object} 包含 base64 格式密钥和 IV 的对象
|
|
13
|
+
* @returns {Object} 包含 Base64 格式密钥和 IV 的对象
|
|
15
14
|
*/
|
|
16
15
|
function generateKeyAndIV() {
|
|
17
|
-
// 使用
|
|
18
|
-
|
|
19
|
-
const
|
|
20
|
-
const iv = crypto.randomBytes(IV_LENGTH).toString(OUTPUT_FORMAT);
|
|
16
|
+
// 使用 KEY_IV_FORMAT (Base64) 输出,以便于存储和传输
|
|
17
|
+
const key = crypto.randomBytes(KEY_LENGTH).toString(KEY_IV_FORMAT);
|
|
18
|
+
const iv = crypto.randomBytes(IV_LENGTH).toString(KEY_IV_FORMAT);
|
|
21
19
|
|
|
22
20
|
return {
|
|
23
|
-
key: key, // Base64 格式的 16
|
|
24
|
-
iv: iv // Base64 格式的 16 字节 IV
|
|
21
|
+
key: key, // Base64 格式的 16 字节密钥(长度为 24 的字符串)
|
|
22
|
+
iv: iv // Base64 格式的 16 字节 IV(长度为 24 的字符串)
|
|
25
23
|
};
|
|
26
24
|
}
|
|
27
|
-
// 示例用法:
|
|
28
|
-
// const { key, iv } = generateKeyAndIV();
|
|
29
|
-
// console.log("Key:", key);
|
|
30
|
-
// console.log("IV:", iv);
|
|
31
|
-
|
|
32
25
|
|
|
33
26
|
/**
|
|
34
27
|
* 检查密钥和初始化向量的长度是否符合 AES-128-CBC 规范。
|
|
28
|
+
* 注意:这里的 Buffer 长度必须是 KEY_LENGTH/IV_LENGTH (16 字节)
|
|
35
29
|
* @param {Buffer} keyBuffer 密钥 Buffer
|
|
36
30
|
* @param {Buffer} ivBuffer 初始化向量 Buffer
|
|
37
31
|
*/
|
|
38
32
|
function checkKeyAndIV(keyBuffer, ivBuffer) {
|
|
39
33
|
if (keyBuffer.length !== KEY_LENGTH) {
|
|
40
|
-
throw new Error(`Invalid Key Length. Key must be ${KEY_LENGTH} bytes for ${ALGORITHM}
|
|
34
|
+
throw new Error(`Invalid Key Length. Key must be ${KEY_LENGTH} bytes for ${ALGORITHM}. Current buffer size: ${keyBuffer.length}`);
|
|
41
35
|
}
|
|
42
36
|
if (ivBuffer.length !== IV_LENGTH) {
|
|
43
|
-
throw new Error(`Invalid IV Length. IV must be ${IV_LENGTH} bytes for ${ALGORITHM}
|
|
37
|
+
throw new Error(`Invalid IV Length. IV must be ${IV_LENGTH} bytes for ${ALGORITHM}. Current buffer size: ${ivBuffer.length}`);
|
|
44
38
|
}
|
|
45
39
|
}
|
|
46
40
|
|
|
47
41
|
/**
|
|
48
42
|
* 🔐 AES-128-CBC 加密
|
|
49
|
-
* 使用内置 crypto 模块,默认使用 PKCS7 自动补位。
|
|
50
43
|
* @param {Object} params
|
|
51
44
|
* @param {string} params.text - 明文
|
|
52
|
-
* @param {string} params.key -
|
|
53
|
-
* @param {string} params.iv -
|
|
45
|
+
* @param {string} params.key - Base64 格式的密钥字符串
|
|
46
|
+
* @param {string} params.iv - Base64 格式的初始化向量字符串
|
|
54
47
|
* @returns {string} Base64 格式的密文
|
|
55
48
|
*/
|
|
56
49
|
function aesEncrypt({ text, key, iv }) {
|
|
57
50
|
try {
|
|
58
|
-
|
|
59
|
-
const
|
|
51
|
+
// 关键修复:使用 KEY_IV_FORMAT (Base64) 来解析输入的 Key 和 IV 字符串
|
|
52
|
+
const keyBuffer = Buffer.from(key, KEY_IV_FORMAT);
|
|
53
|
+
const ivBuffer = Buffer.from(iv, KEY_IV_FORMAT);
|
|
60
54
|
|
|
61
55
|
checkKeyAndIV(keyBuffer, ivBuffer);
|
|
62
56
|
|
|
63
|
-
// 1. 创建加密器,默认自动 PKCS7 补位
|
|
64
57
|
const cipher = crypto.createCipheriv(ALGORITHM, keyBuffer, ivBuffer);
|
|
65
58
|
|
|
66
|
-
//
|
|
67
|
-
|
|
68
|
-
let encrypted = cipher.update(text, INPUT_ENCODING, 'hex');
|
|
59
|
+
// 加密主体:输入是明文 (PLAINTEXT_ENCODING),输出为 Hex
|
|
60
|
+
let encrypted = cipher.update(text, PLAINTEXT_ENCODING, 'hex');
|
|
69
61
|
|
|
70
|
-
//
|
|
62
|
+
// 完成加密,并应用最终补位
|
|
71
63
|
encrypted += cipher.final('hex');
|
|
72
64
|
|
|
73
|
-
//
|
|
74
|
-
return Buffer.from(encrypted, 'hex').toString(
|
|
65
|
+
// 将 Hex 转换为 Base64 输出
|
|
66
|
+
return Buffer.from(encrypted, 'hex').toString(CIPHER_OUTPUT_FORMAT);
|
|
75
67
|
|
|
76
68
|
} catch (error) {
|
|
77
69
|
console.error("AES Encryption Error:", error.message);
|
|
@@ -81,31 +73,31 @@ function aesEncrypt({ text, key, iv }) {
|
|
|
81
73
|
|
|
82
74
|
/**
|
|
83
75
|
* 🔓 AES-128-CBC 解密
|
|
84
|
-
* 使用内置 crypto 模块,自动移除 PKCS7 补位。
|
|
85
76
|
* @param {Object} params
|
|
86
77
|
* @param {string} params.text - Base64 格式的密文
|
|
87
|
-
* @param {string} params.key -
|
|
88
|
-
* @param {string} params.iv -
|
|
78
|
+
* @param {string} params.key - Base64 格式的密钥字符串
|
|
79
|
+
* @param {string} params.iv - Base64 格式的初始化向量字符串
|
|
89
80
|
* @returns {string} 明文
|
|
90
81
|
*/
|
|
91
82
|
function aesDecrypt({ text, key, iv }) {
|
|
92
83
|
try {
|
|
93
|
-
|
|
94
|
-
const
|
|
84
|
+
// 关键修复:使用 KEY_IV_FORMAT (Base64) 来解析输入的 Key 和 IV 字符串
|
|
85
|
+
const keyBuffer = Buffer.from(key, KEY_IV_FORMAT);
|
|
86
|
+
const ivBuffer = Buffer.from(iv, KEY_IV_FORMAT);
|
|
87
|
+
|
|
95
88
|
checkKeyAndIV(keyBuffer, ivBuffer);
|
|
96
89
|
|
|
97
90
|
// 1. 将 Base64 密文转为 Buffer
|
|
98
|
-
const encryptedBuffer = Buffer.from(text,
|
|
91
|
+
const encryptedBuffer = Buffer.from(text, CIPHER_OUTPUT_FORMAT);
|
|
99
92
|
|
|
100
|
-
// 2.
|
|
93
|
+
// 2. 创建解密器
|
|
101
94
|
const decipher = crypto.createDecipheriv(ALGORITHM, keyBuffer, ivBuffer);
|
|
102
95
|
|
|
103
|
-
// 3.
|
|
104
|
-
|
|
105
|
-
let decrypted = decipher.update(encryptedBuffer, 'buffer', INPUT_ENCODING);
|
|
96
|
+
// 3. 解密主体:输入是 Buffer,输出为明文编码
|
|
97
|
+
let decrypted = decipher.update(encryptedBuffer, 'buffer', PLAINTEXT_ENCODING);
|
|
106
98
|
|
|
107
99
|
// 4. 完成解密,并移除补位
|
|
108
|
-
decrypted += decipher.final(
|
|
100
|
+
decrypted += decipher.final(PLAINTEXT_ENCODING);
|
|
109
101
|
|
|
110
102
|
return decrypted;
|
|
111
103
|
} catch (error) {
|
|
@@ -115,8 +107,27 @@ function aesDecrypt({ text, key, iv }) {
|
|
|
115
107
|
}
|
|
116
108
|
}
|
|
117
109
|
|
|
110
|
+
// --- 测试和导出 ---
|
|
111
|
+
|
|
112
|
+
// 测试代码部分(请在文件外部执行时使用,或在 Node.js 环境中移除 export default 后测试)
|
|
113
|
+
/*
|
|
114
|
+
const { key, iv } = generateKeyAndIV()
|
|
115
|
+
console.log("Key:", key);
|
|
116
|
+
console.log(key.length); // 应该是 Base64 字符串长度 24
|
|
117
|
+
console.log("IV:", iv);
|
|
118
|
+
console.log(iv.length); // 应该是 Base64 字符串长度 24
|
|
119
|
+
const text = 'Hello Gemini'
|
|
120
|
+
try {
|
|
121
|
+
const ciphertext = aesEncrypt({text: text, key, iv})
|
|
122
|
+
console.log('加密测试:', ciphertext)
|
|
123
|
+
const decryptedText = aesDecrypt({text: ciphertext, key, iv})
|
|
124
|
+
console.log('解密测试:', decryptedText)
|
|
125
|
+
} catch (e) {
|
|
126
|
+
console.error('测试失败:', e.message)
|
|
127
|
+
}
|
|
128
|
+
*/
|
|
129
|
+
|
|
118
130
|
export default {
|
|
119
|
-
// 推荐使用
|
|
120
131
|
generateKeyAndIV,
|
|
121
132
|
checkKeyAndIV,
|
|
122
133
|
aesEncrypt,
|
package/src/libs/crypto/RSA.js
CHANGED
|
@@ -5,6 +5,29 @@ const ALGORITHM = 'RSA-SHA256';
|
|
|
5
5
|
const INPUT_ENCODING = 'utf8';
|
|
6
6
|
const SIGNATURE_FORMAT = 'base64';
|
|
7
7
|
|
|
8
|
+
/**
|
|
9
|
+
* 🔑 生成 RSA 密钥对 (公钥和私钥)。
|
|
10
|
+
*
|
|
11
|
+
* @returns {Object} 包含公钥和私钥的对象 (PEM 格式)
|
|
12
|
+
*/
|
|
13
|
+
function generateRSAKeyPair() {
|
|
14
|
+
// 使用 generateKeyPairSync 同步生成 RSA 密钥对
|
|
15
|
+
const { publicKey, privateKey } = crypto.generateKeyPairSync('rsa', {
|
|
16
|
+
modulusLength: 2048, // 密钥长度,2048 位是目前推荐的最小安全长度
|
|
17
|
+
publicKeyEncoding: {
|
|
18
|
+
type: 'spki', // SubjectPublicKeyInfo 格式
|
|
19
|
+
format: 'pem' // PEM 格式
|
|
20
|
+
},
|
|
21
|
+
privateKeyEncoding: {
|
|
22
|
+
type: 'pkcs8', // PKCS#8 格式
|
|
23
|
+
format: 'pem' // PEM 格式
|
|
24
|
+
// 生产环境建议添加 cipher: 'aes-256-cbc' 和 passphrase 来加密私钥
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
return { publicKey, privateKey };
|
|
29
|
+
}
|
|
30
|
+
|
|
8
31
|
/**
|
|
9
32
|
* 🔐 RSA 签名
|
|
10
33
|
* 使用 'RSA-SHA256' 算法,将输入文本进行签名。
|
|
@@ -21,20 +44,15 @@ function rsaSign({ text, privateKey }) {
|
|
|
21
44
|
}
|
|
22
45
|
|
|
23
46
|
try {
|
|
24
|
-
// 使用 const 声明,保持不变性
|
|
25
47
|
const signer = crypto.createSign(ALGORITHM);
|
|
26
|
-
|
|
27
|
-
// 优化:将数据直接传递给 update,无需再调用 end()
|
|
28
48
|
signer.update(text, INPUT_ENCODING);
|
|
29
49
|
|
|
30
|
-
//
|
|
31
|
-
// 'base64' 是默认格式,但显式指定更清晰
|
|
50
|
+
// 签名
|
|
32
51
|
const signature = signer.sign(privateKey, SIGNATURE_FORMAT);
|
|
33
52
|
|
|
34
53
|
return signature;
|
|
35
54
|
|
|
36
55
|
} catch (error) {
|
|
37
|
-
// 捕获密钥格式错误、权限错误等
|
|
38
56
|
console.error(`RSA Signing Error (${ALGORITHM}):`, error.message);
|
|
39
57
|
throw new Error("RSA signing failed. Check private key format and validity.");
|
|
40
58
|
}
|
|
@@ -53,21 +71,15 @@ function rsaSign({ text, privateKey }) {
|
|
|
53
71
|
*/
|
|
54
72
|
function rsaVerify({ text, signature, publicKey }) {
|
|
55
73
|
if (!text || !signature || !publicKey) {
|
|
56
|
-
// 参数缺失时,直接返回 false 或抛出错误,这里选择返回 false 兼容原逻辑,但推荐抛出错误
|
|
57
74
|
console.warn("Missing required parameters for verification.");
|
|
58
75
|
return false;
|
|
59
76
|
}
|
|
60
77
|
|
|
61
78
|
try {
|
|
62
|
-
// 使用 const 声明
|
|
63
79
|
const verifier = crypto.createVerify(ALGORITHM);
|
|
64
|
-
|
|
65
|
-
// 优化:将数据直接传递给 update
|
|
66
80
|
verifier.update(text, INPUT_ENCODING);
|
|
67
81
|
|
|
68
82
|
// 验证签名
|
|
69
|
-
// signature 已经是 Base64 格式的 Buffer,不需要再调用 Buffer.from() 转换
|
|
70
|
-
// verifier.verify 会自动处理公钥和签名格式
|
|
71
83
|
return verifier.verify(
|
|
72
84
|
publicKey,
|
|
73
85
|
signature,
|
|
@@ -75,14 +87,54 @@ function rsaVerify({ text, signature, publicKey }) {
|
|
|
75
87
|
);
|
|
76
88
|
|
|
77
89
|
} catch (error) {
|
|
78
|
-
// 捕获公钥格式错误等
|
|
79
90
|
console.error(`RSA Verification Error (${ALGORITHM}):`, error.message);
|
|
80
|
-
// 验证过程失败通常意味着配置或密钥有误,应抛出错误而不是返回 false
|
|
81
91
|
throw new Error("RSA verification failed due to internal error. Check public key format and validity.");
|
|
82
92
|
}
|
|
83
93
|
}
|
|
84
94
|
|
|
95
|
+
/* --- 测试代码 ---
|
|
96
|
+
try {
|
|
97
|
+
const dataToSign = "这是一段需要使用数字签名的重要数据。";
|
|
98
|
+
|
|
99
|
+
// 1. 生成密钥对
|
|
100
|
+
console.log("--- 1. 生成 RSA 密钥对 ---");
|
|
101
|
+
const { publicKey, privateKey } = generateRSAKeyPair();
|
|
102
|
+
// console.log("私钥 (PEM):", privateKey);
|
|
103
|
+
// console.log("公钥 (PEM):", publicKey);
|
|
104
|
+
|
|
105
|
+
// 2. 使用私钥签名
|
|
106
|
+
console.log("\n--- 2. 进行签名 ---");
|
|
107
|
+
const signature = rsaSign({ text: dataToSign, privateKey: privateKey });
|
|
108
|
+
console.log("原始数据:", dataToSign);
|
|
109
|
+
console.log("签名结果 (Base64):", signature);
|
|
110
|
+
|
|
111
|
+
// 3. 使用公钥验证
|
|
112
|
+
console.log("\n--- 3. 验证签名 ---");
|
|
113
|
+
const isValid = rsaVerify({
|
|
114
|
+
text: dataToSign,
|
|
115
|
+
signature: signature,
|
|
116
|
+
publicKey: publicKey
|
|
117
|
+
});
|
|
118
|
+
console.log("验证结果 (正确签名):", isValid ? "✅ 验证通过" : "❌ 验证失败");
|
|
119
|
+
|
|
120
|
+
// 4. 验证失败场景 (数据篡改)
|
|
121
|
+
console.log("\n--- 4. 验证失败测试 (数据篡改) ---");
|
|
122
|
+
const tamperedData = "这是一段被篡改后的数据!";
|
|
123
|
+
const isInvalid = rsaVerify({
|
|
124
|
+
text: tamperedData, // 使用篡改后的数据
|
|
125
|
+
signature: signature,
|
|
126
|
+
publicKey: publicKey
|
|
127
|
+
});
|
|
128
|
+
console.log("验证结果 (篡改数据):", isInvalid ? "❌ 验证通过 (错误)" : "✅ 验证失败 (正确)");
|
|
129
|
+
|
|
130
|
+
} catch (error) {
|
|
131
|
+
console.error("\n--- RSA 测试发生错误 ---");
|
|
132
|
+
console.error(error.message);
|
|
133
|
+
}
|
|
134
|
+
*/
|
|
135
|
+
|
|
85
136
|
export default {
|
|
86
|
-
|
|
137
|
+
generateRSAKeyPair,
|
|
138
|
+
rsaSign,
|
|
87
139
|
rsaVerify
|
|
88
|
-
}
|
|
140
|
+
}
|