要在 Java 中生成 ECC 非对称密钥,并在 JavaScript 端使用公钥进行加密,最后在 Java 端解密,我们可以按照以下步骤进行:
1. 在 Java 中生成 ECC 密钥对
首先,我们需要在 Java 中生成一个 ECC 密钥对。我们将使用 java.security
包来实现。
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.util.Base64;
public class ECCKeyPairGenerator {
public static void main(String[] args) throws Exception {
// 使用 SHA256withECDSA 曲线生成密钥对
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("EC");
keyGen.initialize(256, new SecureRandom()); // 使用256位的ECC
KeyPair keyPair = keyGen.generateKeyPair();
PublicKey publicKey = keyPair.getPublic();
PrivateKey privateKey = keyPair.getPrivate();
// 打印公钥和私钥为 Base64 编码格式
String publicKeyBase64 = Base64.getEncoder().encodeToString(publicKey.getEncoded());
String privateKeyBase64 = Base64.getEncoder().encodeToString(privateKey.getEncoded());
System.out.println("Public Key: " + publicKeyBase64);
System.out.println("Private Key: " + privateKeyBase64);
}
}
运行此代码后,它会输出一个 ECC 公钥和私钥,您可以将公钥传递给前端以供加密。
2. 在 JavaScript 中使用公钥加密数据
接下来,我们将在 JavaScript(假设是在浏览器或 Node.js 环境中)中使用上述公钥进行数据加密。这里我们使用 Web Crypto API 来实现这个过程。
async function importPublicKey(pem) {
const binaryDerString = window.atob(pem);
const binaryDer = new Uint8Array(binaryDerString.length);
for (let i = 0; i < binaryDerString.length; i++) {
binaryDer[i] = binaryDerString.charCodeAt(i);
}
return await window.crypto.subtle.importKey(
'spki',
binaryDer.buffer,
{ name: 'ECDH', namedCurve: 'P-256' }, // P-256 对应于 256 位ECC
true,
['encrypt']
);
}
async function encryptData(publicKey, data) {
const encodedData = new TextEncoder().encode(data);
const encryptedData = await window.crypto.subtle.encrypt(
{
name: 'ECDH',
// 用于加密的算法参数,可以选择不同的模式,比如 AES-GCM 或者其他
length: 128
},
publicKey,
encodedData
);
return encryptedData;
}
// 示例用法
const pemPublicKey = "-----BEGIN PUBLIC KEY-----\nYOUR_PUBLIC_KEY_HERE\n-----END PUBLIC KEY-----"; // 替换为你的公钥
(async () => {
try {
const publickeyObj = await importPublicKey(pemPublicKey);
const dataToEncrypt = "Hello, World!";
const encryptedDataBuffer = await encryptData(publickeyObj, dataToEncrypt);
console.log(new Uint8Array(encryptedDataBuffer)); // 输出加密后的数据(Uint8Array格式)
} catch (error) {
console.error(error);
}
})();
请确保将 YOUR_PUBLIC_KEY_HERE
替换为您从上面获取的实际公钥 Base64 字符串,并注意去掉 PEM 格式的头部和尾部。
3. 在 Java 中解密数据
最后,在 Java 中解密刚刚用公共信息加密的数据。我们需要先从客户端获取到被加密的数据,然后用私有键来解密它。
import javax.crypto.Cipher;
import javax.crypto.spec.PKCS8EncodedKeySpec;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.util.Base64;
public class ECCDecryptionExample {
public static void main(String[] args) throws Exception {
String privateKeyBase64 = "YOUR_PRIVATE_KEY_BASE64_STRING"; // 替换为你的私有键
byte[] decodedPrivateBytes = Base64.getDecoder().decode(privateKeyBase64);
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(decodedPrivateBytes);
KeyFactory factory = KeyFactory.getInstance("EC");
PrivateKey privatekeyObj= factory.generatePrivate(spec);
// 假设encryptedData是JavaScript返回的字节数组,你需要把它转化成byte[]
byte[] encryptedDataBytes;
Cipher cipherDecrypt= Cipher.getInstance("ECIES");
cipherDecrypt.init(Cipher.DECRYPT_MODE,privatekeyObj);
byte[] decryptedBytes=cipherDecrypt.doFinal(encryptedDataBytes);
String decryptedText=new String(decryptedBytes);
System.out.println(decryptedText);
}
}
注意事项:
- 确保你在服务器与客户端之间正确传输了加密/解密所需的数据。
- 根据具体需求,可能需要调整密码算法、填充模式等设置,以便于相互兼容。
- 上述代码仅提供了基本结构,可能还需根据具体环境进行适当调整和错误处理。
内容由零声教学AI助手提供,问题来源于学员提问