ZBLOG

java生成Ecc非对称密钥,js端使用公钥加密,java端解密

要在 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);  
     }
}

注意事项:

  1. 确保你在服务器与客户端之间正确传输了加密/解密所需的数据。
  2. 根据具体需求,可能需要调整密码算法、填充模式等设置,以便于相互兼容。
  3. 上述代码仅提供了基本结构,可能还需根据具体环境进行适当调整和错误处理。


    内容由零声教学AI助手提供,问题来源于学员提问

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://golang.0voice.com/?id=20972

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?