有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

节点。js如何使用java生成的public对nodejs中的字符串进行加密

我想在将密码发送到Springboot API之前对其进行加密。我的想法是:-

  1. 在java中生成公钥和私钥
  2. 对公钥和私钥执行base64编码
  3. 在节点(角度)端使用编码公钥,这将用于加密
  4. 在springboot rest api中使用编码的私钥,这将用于解密

下面是我生成、加密和解密密码的java代码

RSAKeyPairGenerator。java

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;

public class RSAKeyPairGenerator {
    private static String privateKeyString = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBALyR1WRqVBuvdmXmgrcZ4VMY4hIFTYt63NGEN9atlgnngNliMasvzBofnjRtk5mukezUKujtON6mPnAjKJoEDdiaw3Rk0hKvgW5MszyUBE5bLThexVLbi+nQYSf2GSvd0fjdZn6KjhgVOdbYe+JduU/iPD3/Ti5p+w3MewgZpy2RAgMBAAECgYAqWdqCXfsb6LF/u2C6PN7Faf5EK9q5q9NyXu6nkX70JIFk0U/0cZy2dUlz3vRafMGbXh9xBu5R2yaEyvCwfp6ZF26A8MbS/IaI53LMKmyclhES2f3tZLKUPkg6fntz+e6e/6oSDdQPHP3J2QrpuwzyW+UZJQmmYYj7f9sq/+dawQJBAOnkHWkLuIZNIgLzV0TuHA6fcOXrqrSlS1/Q0qLyaQEZOObocXDvWaCSP+8RXiqZSwAnMJbrGHQA5ULXLWI4GjkCQQDOZP6bfn2VV3m8JSlYL9Uz4TrRYb8Qe3/mohhMsyDB7Ua/6d9BV7JZgbYiXP0utobKVWLxD49OFMkgEs20qY4ZAkB4dJsQ9pBZ2m+hxWE0hsy8WzDxuKV504c2GX3hnaamgi7j/OIvn5UxNSDoJrGwjrIpqgVENF+rnqpz+g3Nf8dBAkBV/op+6yMUGFBmbe1eCwAAD7XcC6f6DBrsU1lgi7n4Uw6JY75bkViEJqFmi+wJjI94uj7xRZRl6g8qx+rhfUvxAkEArD1we6ZLTWz73D8z+4Boj7Su7b5LhfgvXVL5V4Zdog3X58pHK+dYppapDh5KjZZdor+y/6uz1PqIs2dmFy/xtQ==";
    private static String publicKeyString = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC8kdVkalQbr3Zl5oK3GeFTGOISBU2LetzRhDfWrZYJ54DZYjGrL8waH540bZOZrpHs1Cro7Tjepj5wIyiaBA3YmsN0ZNISr4FuTLM8lAROWy04XsVS24vp0GEn9hkr3dH43WZ+io4YFTnW2HviXblP4jw9/04uafsNzHsIGactkQIDAQAB";
    private static PrivateKey privateKey;
    private static PublicKey publicKey;
    
    public void generateKeys() throws NoSuchAlgorithmException {
        KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
        keyGen.initialize(1024);
        KeyPair pair = keyGen.generateKeyPair();
        RSAKeyPairGenerator.privateKey = pair.getPrivate();
        RSAKeyPairGenerator.publicKey = pair.getPublic();
    }
    
    public void readKeys() throws NoSuchAlgorithmException, InvalidKeySpecException {
        KeyFactory kf = KeyFactory.getInstance("RSA");

        byte [] encoded = Base64.getDecoder().decode(privateKeyString);
        PKCS8EncodedKeySpec keySpec1 = new PKCS8EncodedKeySpec(encoded);
        RSAKeyPairGenerator.privateKey = kf.generatePrivate(keySpec1);
        
        encoded = Base64.getDecoder().decode(publicKeyString);
        X509EncodedKeySpec keySpec2 = new X509EncodedKeySpec(encoded);
        RSAKeyPairGenerator.publicKey = kf.generatePublic(keySpec2);
    }

    public static void main(String[] args) throws NoSuchAlgorithmException, IOException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, InvalidKeySpecException {
        RSAKeyPairGenerator keyPairGenerator = new RSAKeyPairGenerator();
        // Next line is for testing with encrypted text generated by nodejs code with genrated keys
        // keyPairGenerator.generateKeys();
        keyPairGenerator.readKeys();
        
        System.out.println("-----Private----------");
        System.out.println(Base64.getEncoder().encodeToString(privateKey.getEncoded()));
        System.out.println("Encoding : "+ privateKey.getFormat());
        System.out.println("----------------------");
        
        System.out.println("-----Public----------");
        System.out.println(Base64.getEncoder().encodeToString(publicKey.getEncoded()));
        System.out.println("Encoding : "+ publicKey.getFormat());
        System.out.println("----------------------");
        
        String secretMessage = "Test";
        System.out.println(secretMessage);
        
        Cipher encryptCipher = Cipher.getInstance("RSA");
        encryptCipher.init(Cipher.ENCRYPT_MODE, publicKey);
        
        byte[] secretMessageBytes = secretMessage.getBytes(StandardCharsets.UTF_8);
        byte[] encryptedMessageBytes = encryptCipher.doFinal(secretMessageBytes);
        // Next lines are for testing decryption with encrypted text generated by nodejs code with generated keys
        // byte[] encryptedMessageBytes = "B��u���<⌂׷�lǚm0�W������1�%EN�7��‼��l��l�<�����k;�������GĦ9D8��Z��I�Oɺ♫��→P'�§�{k�Ɋ+-}?��rZ".getBytes();
        // byte[] encryptedMessageBytes =  Base64.getDecoder().decode("woboAUytDXJLlKm7zbqNdxVORG+kio9kZxvMPOHruQfxwNEx7SVFTsw3oeETqbRs4NZskjzO2Nzjyms73vv758Dcy0fEpjlEOKmrWuG62knOT8m6DqGDGlAn1hXpe2u6yYorLX0/6fhyWg1C/JR1sbaKPH/Xt+Fsx5ptMONX0uw=");
        System.out.println(new String(encryptedMessageBytes));
                
        Cipher decryptCipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA1AndMGF1Padding");
        decryptCipher.init(Cipher.DECRYPT_MODE, privateKey);
        
        byte[] decryptedMessageBytes = decryptCipher.doFinal(encryptedMessageBytes);
        String decryptedMessage = new String(decryptedMessageBytes, StandardCharsets.UTF_8);
        System.out.println(decryptedMessage);
    }
}

这给了我以下输出

-----Private----------
MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAMv+t+D6/7ZY6m+CjD97NB989P2YjmGcE2yHUokyjmxVi/SxIu9MboiVNewR+mFjTFYPGgMWHz1/XeVGlinjN/5+0fdiO/JEvEUilFmkkIF3My11I09b9NZ9RJmpCNCbqOg7NSt6VD8IC/w19N25xwcofc3qbgfEjKSs0CgxfahrAgMBAAECgYEAiyLlEBKiryDeZchJGFNULdXw07dmBbWKmg+CgAl3kvSWTQM0rLsY+Rese6OXfy1XN6t9NnW0QSHKTUNj0JYl7btKEblVHERbjwavUe83tcNIc3o0xrGoBAzma14ZicPYm70JWixTO778lm5AXKl504+oOQyVYmfgXcevPXwdIkECQQDvO3DBuu6wp5nbwR4t0736HOH9jVIjJOS8oABUARDhNt1fkb8uEptDr5EomVRMqarJMAjSMpYxrUCpvgtf4nZ5AkEA2ksDr8pbbFvZPaAe0F43LmJtFM3PvCz87S93p20YjwVMmGV17sJ5t7a26HtubgRLEWq4z6rxq2oXPv4y1lstAwJAbj9cVUtKWIrEcutqdwAPmsXYt7p60ctcxjiOLihXmRJprnNCQX89olG0eZs/qBzAofrK9eNuJ/KJzC/SmhuJMQJAAz9gc6oQCCGprrgGHVV5frAqLUgOkh8dOC4fmpcN6XrLs+y2f3HXO7t1JypG704TC9RJoZVKeSFf7Sj8+qFqnwJBALRiQc9SG5Ht5TLo12W4l3bRaxpbo597BgKRjz3hqiySdqjZA9Qe84qmEKveZ9eWehbfqwzKmCbW43I1ZEFZ95o=
Encoding : PKCS#8
----------------------
-----Public----------
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDL/rfg+v+2WOpvgow/ezQffPT9mI5hnBNsh1KJMo5sVYv0sSLvTG6IlTXsEfphY0xWDxoDFh89f13lRpYp4zf+ftH3YjvyRLxFIpRZpJCBdzMtdSNPW/TWfUSZqQjQm6joOzUrelQ/CAv8NfTduccHKH3N6m4HxIykrNAoMX2oawIDAQAB
Encoding : X.509
----------------------
Test
�N::�`��\A���ƈ�~��5s���
�0�I�C�uƹx2�Z&Kں�"ьC�$
q��K���h�^<�5�E�Ɨ0B�͒Z�{��EDbDH�.��#:�e��h~j���������q�c��R�
Test

在Nodejs端,我使用上面的public来加密我的文本

索引。js

const crypto = require("crypto");

var pubkey = "-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDL/rfg+v+2WOpvgow/ezQffPT9mI5hnBNsh1KJMo5sVYv0sSLvTG6IlTXsEfphY0xWDxoDFh89f13lRpYp4zf+ftH3YjvyRLxFIpRZpJCBdzMtdSNPW/TWfUSZqQjQm6joOzUrelQ/CAv8NfTduccHKH3N6m4HxIykrNAoMX2oawIDAQAB\n-----END PUBLIC KEY-----";

var plaintext = "Test"
var buffer = new Buffer.from(plaintext, "utf8");
var enc = crypto.publicEncrypt(pubkey, buffer);
var bs64 = enc.toString('base64');

console.log(enc.toString());
console.log(enc.toString('base64'));

这给了我以下输出

B��u���<⌂׷�lǚm0�W������1�%EN�7��‼��l��l�<�����k;�������GĦ9D8��Z��I�Oɺ♫��→P'�§�{k�Ɋ+-}?��rZ
woboAUytDXJLlKm7zbqNdxVORG+kio9kZxvMPOHruQfxwNEx7SVFTsw3oeETqbRs4NZskjzO2Nzjyms73vv758Dcy0fEpjlEOKmrWuG62knOT8m6DqGDGlAn1hXpe2u6yYorLX0/6fhyWg1C/JR1sbaKPH/Xt+Fsx5ptMONX0uw=

现在我尝试在java端使用这两个字符串进行解密

当我尝试解码字符串时,它会给我以下错误

Exception in thread "main" javax.crypto.IllegalBlockSizeException: Data must not be longer than 128 bytes
    at com.sun.crypto.provider.RSACipher.doFinal(RSACipher.java:346)
    at com.sun.crypto.provider.RSACipher.engineDoFinal(RSACipher.java:391)
    at javax.crypto.Cipher.doFinal(Cipher.java:2168)
    at com.mindtree.starr.wsr.RSAKeyPairGenerator.main(RSAKeyPairGenerator.java:90)

当我尝试解码base64字符串时,它会告诉我以下错误

Exception in thread "main" javax.crypto.BadPaddingException: Decryption error
    at sun.security.rsa.RSAPadding.unpadV15(RSAPadding.java:379)
    at sun.security.rsa.RSAPadding.unpad(RSAPadding.java:290)
    at com.sun.crypto.provider.RSACipher.doFinal(RSACipher.java:365)
    at com.sun.crypto.provider.RSACipher.engineDoFinal(RSACipher.java:391)
    at javax.crypto.Cipher.doFinal(Cipher.java:2168)
    at com.mindtree.starr.wsr.RSAKeyPairGenerator.main(RSAKeyPairGenerator.java:90)

我做错了什么


共 (1) 个答案

  1. # 1 楼答案

    第一条评论中明确描述了问题,第二条评论中给出了解决方案

    适用于我的密码实例的正确转换字符串为RSA/ECB/OAEPWithSHA-1AndMGF1Padding

    下面是解密密码的实例,效果很好

    Cipher decryptCipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-1AndMGF1Padding");