我有以下使用RSA公钥和私钥进行加密和解密的Java代码。
我在GO中编写了类似的代码来做同样的事情。
但是当我尝试使用以Java代码加密的Go代码解密字符串时,我看到错误: crypto / rsa:解密错误
public class EncryptDecryptUtil {
private static final String MODE = "RSA/None/OAEPWithSHA256AndMGF1Padding";
private static EncryptDecryptUtil single_instance = null;
public static EncryptDecryptUtil getInstance()
{
if (single_instance == null)
single_instance = new EncryptDecryptUtil();
return single_instance;
}
public static String encryptText(String text, String keyStr) throws Exception {
String resultText = null;
try {
Security.addProvider(new BouncyCastleProvider());
Key publicKey = getRSAPublicFromPemFormat(keyStr);
Cipher cipher = Cipher.getInstance(MODE, "BC");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
resultText = new String(Base64.getUrlEncoder().encodeToString(cipher.doFinal(text.getBytes())));
} catch (IOException | GeneralSecurityException e) {
e.printStackTrace();
}
return resultText;
}
public static String decryptText(String text, String keyStr) throws Exception {
String resultText = null;
try {
Security.addProvider(new BouncyCastleProvider());
Key privateKey = getRSAPrivateFromPemFormat(keyStr);
Cipher cipher = Cipher.getInstance(MODE, "BC");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
resultText = new String(cipher.doFinal(Base64.getUrlDecoder().decode(text.getBytes())));
} catch (IOException | GeneralSecurityException e) {
e.printStackTrace();
}
return resultText;
}
private static PrivateKey getRSAPrivateFromPemFormat(String keyStr) throws Exception {
return (PrivateKey) getKeyFromPEMString(keyStr, data -> new PKCS8EncodedKeySpec(data), (kf, spec) -> {
try {
return kf.generatePrivate(spec);
} catch (InvalidKeySpecException e) {
System.out.println("Cannot generate PrivateKey from String : " + keyStr + e);
return null;
}
});
}
private static PublicKey getRSAPublicFromPemFormat(String keyStr) throws Exception {
return (PublicKey) getKeyFromPEMString(keyStr, data -> new X509EncodedKeySpec(data), (kf, spec) -> {
try {
return kf.generatePublic(spec);
} catch (InvalidKeySpecException e) {
System.out.println("Cannot generate PublicKey from String : " + keyStr + e);
return null;
}
});
}
private static Key getKeyFromPEMString(String key, Function<byte[], EncodedKeySpec> buildSpec,
BiFunction<KeyFactory, EncodedKeySpec, ? extends Key> getKey) throws Exception {
try {
// Read PEM Format
PemReader pemReader = new PemReader(new StringReader(key));
PemObject pemObject = pemReader.readPemObject();
pemReader.close();
KeyFactory kf = KeyFactory.getInstance("RSA", "BC");
return getKey.apply(kf, buildSpec.apply(pemObject.getContent()));
} catch (Exception e) {
throw new Exception(e.getMessage());
}
}
}
package encryption
import (
"crypto/rand"
"crypto/rsa"
"crypto/sha512"
"crypto/x509"
"encoding/base64"
"encoding/pem"
"fmt"
"io/ioutil"
"log"
)
// Encrypt encrypts string with public key
func Encrypt(msg string, publicKeyFilePath string) (string, error) {
pubKey, err := ReadPublicKey(publicKeyFilePath)
if err != nil {
return "", err
}
encrypted, err := encrypt([]byte(msg), pubKey)
if err != nil {
return "", err
}
base64Encoded := base64.URLEncoding.WithPadding(61).EncodeToString(encrypted)
return base64Encoded, nil
}
// Decrypt decrypts string with private key
func Decrypt(msg string, privateKeyFilePath string) (string, error) {
privKey, err := ReadPrivateKey(privateKeyFilePath)
if err != nil {
return "", err
}
base64Decoded, err := base64.URLEncoding.WithPadding(61).DecodeString(msg)
if err != nil {
return "", err
}
decrypted, err := decrypt(base64Decoded, privKey)
if err != nil {
return "", err
}
return string(decrypted), nil
}
// GenerateKeyPair generates a new key pair
func GenerateKeyPair(bits int) (*rsa.PrivateKey, *rsa.PublicKey, error) {
privkey, err := rsa.GenerateKey(rand.Reader, bits)
if err != nil {
return nil, nil, fmt.Errorf("Error generating Key Pair: %s", err)
}
return privkey, &privkey.PublicKey, nil
}
// ReadPublicKey reads public key from a file
func ReadPublicKey(publicKeyFile string) (*rsa.PublicKey, error) {
pubPemData, err := ioutil.ReadFile(publicKeyFile)
if err != nil {
return nil, fmt.Errorf("Error [%s] reading public key from file: %s", err, publicKeyFile)
}
return BytesToPublicKey(pubPemData)
}
// ReadPrivateKey reads private key from a file
func ReadPrivateKey(privateKeyFile string) (*rsa.PrivateKey, error) {
privKeyData, err := ioutil.ReadFile(privateKeyFile)
if err != nil {
return nil, fmt.Errorf("Error [%s] reading private key from file: %s", err, privateKeyFile)
}
return BytesToPrivateKey(privKeyData)
}
// PrivateKeyToBytes private key to bytes
func PrivateKeyToBytes(priv *rsa.PrivateKey) []byte {
privBytes := pem.EncodeToMemory(
&pem.Block{
Type: "RSA PRIVATE KEY",
Bytes: x509.MarshalPKCS1PrivateKey(priv),
},
)
return privBytes
}
// PublicKeyToBytes public key to bytes
func PublicKeyToBytes(pub *rsa.PublicKey) ([]byte, error) {
pubASN1, err := x509.MarshalPKIXPublicKey(pub)
if err != nil {
return nil, fmt.Errorf("Error converting PublicKey to Bytes: %s", err)
}
pubBytes := pem.EncodeToMemory(&pem.Block{
Type: "RSA PUBLIC KEY",
Bytes: pubASN1,
})
return pubBytes, nil
}
// BytesToPrivateKey bytes to private key
func BytesToPrivateKey(priv []byte) (*rsa.PrivateKey, error) {
block, _ := pem.Decode(priv)
enc := x509.IsEncryptedPEMBlock(block)
b := block.Bytes
var err error
if enc {
log.Println("is encrypted pem block")
b, err = x509.DecryptPEMBlock(block, nil)
if err != nil {
return nil, fmt.Errorf("Error decrypting PEM Block: %s", err)
}
}
key, err := x509.ParsePKCS1PrivateKey(b)
if err != nil {
return nil, fmt.Errorf("Error parsing PKCS1 Private Key: %s", err)
}
return key, nil
}
// BytesToPublicKey bytes to public key
func BytesToPublicKey(pub []byte) (*rsa.PublicKey, error) {
block, _ := pem.Decode(pub)
enc := x509.IsEncryptedPEMBlock(block)
b := block.Bytes
var err error
if enc {
log.Println("is encrypted pem block")
b, err = x509.DecryptPEMBlock(block, nil)
if err != nil {
return nil, fmt.Errorf("Error decrypting PEM Block: %s", err)
}
}
ifc, err := x509.ParsePKIXPublicKey(b)
if err != nil {
return nil, fmt.Errorf("Error parsing PKCS1 Public Key: %s", err)
}
key, ok := ifc.(*rsa.PublicKey)
if !ok {
return nil, fmt.Errorf("Error converting to Public Key: %s", err)
}
return key, nil
}
// encrypt encrypts data with public key
func encrypt(msg []byte, pub *rsa.PublicKey) ([]byte, error) {
hash := sha512.New()
ciphertext, err := rsa.EncryptOAEP(hash, rand.Reader, pub, msg, nil)
if err != nil {
return nil, fmt.Errorf("Error encrypting: %s", err)
}
return ciphertext, nil
}
// Decrypt decrypts data with private key
func decrypt(ciphertext []byte, priv *rsa.PrivateKey) ([]byte, error) {
hash := sha512.New()
plaintext, err := rsa.DecryptOAEP(hash, rand.Reader, priv, ciphertext, nil)
if err != nil {
return nil, fmt.Errorf("Error decrypting: %s", err)
}
return plaintext, nil
}
如何确保Go代码正确解密了使用Java代码加密的值。
答案 0 :(得分:0)
基于@Michael的评论,我将go代码更改为使用sha256.New()而不是sha512.New(),从而解决了该问题。 现在,我可以使用Java进行加密,然后使用Go进行解密。