java - 在 Java 和 Javascript 中使用公钥/私钥加密/解密字符串
问题描述
我正在用 javascript 生成一个公钥和私钥对。公钥被发送到我有加密字符串的java代码的服务器。当我尝试使用私钥解密 Javascript 中的字符串时,出现错误。这是我使用的 Javascript 代码。
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class CryptographyService {
private publicKey: string;
private privateKey: string;
public randomKey: string;
private keyPair: CryptoKeyPair;
public exportedKey: string;
constructor() {
/**Generate the public and private key */
this.generateKeys()
.then(() => {
return this.exportKey(this.keyPair.publicKey);
})
.then(() => {});
}
public setPublicKey(key: string) {
this.publicKey = key;
}
public setRandomKey(key: string) {
this.randomKey = key;
}
public setPrivateKey(key: string) {
this.privateKey = key;
}
public async encryptMessage(text: String) {
const { default: NodeRSA } = await import('node-rsa');
const key = NodeRSA(this.publicKey, 'pkcs8-public');
return key.encrypt(text, 'base64');
}
// For subscription key encryption and decryption
private async generateKeys() {
const keyPair = await crypto.subtle.generateKey(
{
name: 'RSA-OAEP', //algorithm
modulusLength: 2048,
publicExponent: new Uint8Array([1, 0, 1]),
hash: 'SHA-256'
},
true,
['encrypt', 'decrypt']
);
this.keyPair = keyPair; /**{
publicKey:
privateKey:
} */
}
private async exportKey(key: CryptoKey) {
/** exportKey() it takes as input a CryptoKey object and gives you the key in an external, portable format.
* crypto.subtle.exportKey(format, key); : returns a promise
* spki format is used to import/export RSA or Elliptic Curve public keys.
*/
const exported = await crypto.subtle.exportKey('spki', key); //Returns an ArrayBuffer
const exportedAsString = this.ab2str(exported); // Converts ArrayBuffer to String
/**btoa encodes a string to base64 */
const exportedAsBase64 = window.btoa(exportedAsString);
this.exportedKey = exportedAsBase64;
}
// Uses private key to decrypt message sent from the backend
public async decryptMessage(input: string) {
const ciphertext = this.str2ab(input);
const decrypted = await window.crypto.subtle.decrypt(
{
name: 'RSA-OAEP'
},
this.keyPair.privateKey,
ciphertext
);
const dec = new TextDecoder();
const decodedMessage = dec.decode(decrypted);
return decodedMessage;
}
private ab2str(buf) {
return String.fromCharCode.apply(null, new Uint8Array(buf));
}
private str2ab(str) {
const buf = new ArrayBuffer(str.length);
const bufView = new Uint8Array(buf);
for (let i = 0, strLen = str.length; i < strLen; i++) {
bufView[i] = str.charCodeAt(i);
}
return buf;
}
}
将字符串转换为 PublicKey 对象的 java 代码
String pubKey = loginRequest.publicKey;
PublicKey pk = null;
try {
byte[] keyBytes = Base64.decodeBase64(pubKey);
X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
KeyFactory kf = KeyFactory.getInstance("RSA");
pk = kf.generatePublic(spec);
} catch (Exception e) {
System.out.println("Exception in generating primary key: " + e.getMessage());
}
使用 publicKey 加密字符串
public static byte[] encrypt(String text, PublicKey key) {
byte[] cipherText = null;
try {
// get an RSA cipher object and print the provider
final Cipher cipher = Cipher.getInstance(ALGORITHM);
OAEPParameterSpec oaepParams = new OAEPParameterSpec("SHA-256", "MGF1", new MGF1ParameterSpec("SHA-256"), PSource.PSpecified.DEFAULT);
// encrypt the plain text using the public key
cipher.init(Cipher.ENCRYPT_MODE, key, oaepParams);
cipherText = cipher.doFinal(text.getBytes());
} catch (Exception e) {
e.printStackTrace();
}
return cipherText;
}
当我尝试在 Javascript 中对其进行解码时,我得到了一个加密的字符串,我得到了一个错误。知道我需要在代码中更改什么来解决这个问题吗?
解决方案
推荐阅读
- r - 为什么将 filter() 放在不同的位置会给出不同的直方图?
- r - 根据列表中数据框的文件名在大列表中设置数据子集
- r - 理解和重建数据帧重载为 d3 格式
- c# - 如何在邮件模板中使用 App.Resources
- android - 如何发送包含字符串数组和文件数组的多部分
- git - 在 Katalon 工作室 GitHub 集成中创建新分支
- python-3.x - 无法使用 beautifulsoup 刮取表格的所有行
- swift - 有没有办法让 @Published 属性实际上得到更新和发布?
- python - Selenium 在无头模式 Ubuntu 18.04 中无法通过 xpath 获取元素
- python - Scrapy - 如何在已启用 cookie 时修复“请启用 cookie”?