代码之家  ›  专栏  ›  技术社区  ›  Quick Learner

RSA OAEP、Golang Encrypt、Java Decrypt-BadPaddingException:解密错误

  •  2
  • Quick Learner  · 技术社区  · 7 年前

    我正在尝试解密一个使用RSA-OAEP在Golang中加密的字符串。但获取BadPaddingException:解密错误。很难弄清楚我错过了什么。。

    下面是Golang加密方法

    func encryptString() {
    rootPEM := io_related.ReadFile("../../resources/pubkey.pem")
        //fmt.Printf("Cert String %q \n", rootPEM)
    
        block, _ := pem.Decode([]byte(rootPEM))
        var cert *x509.Certificate
        cert, _ = x509.ParseCertificate(block.Bytes)
        rsaPublicKey := cert.PublicKey.(*rsa.PublicKey)
    
        secretMessage := []byte("password")
        label := []byte("")
    
        // crypto/rand.Reader is a good source of entropy for randomizing the
        // encryption function.
        rng := rand.Reader
    
        ciphertext, err := rsa.EncryptOAEP(sha256.New(), rng, rsaPublicKey, secretMessage, label)
        if err != nil {
            fmt.Fprintf(os.Stderr, "Error from encryption: %s\n", err)
            return
        }
    
        // Since encryption is a randomized function, ciphertext will be
        // different each time.
    
        base64EncodedString := base64.StdEncoding.EncodeToString(ciphertext)
        fmt.Println(base64EncodedString)
    }
    

    我的java解密方法为

    public void decryptString(String base64String) throws NoSuchAlgorithmException, CertificateException, IOException, KeyStoreException, UnrecoverableKeyException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException{
            FileInputStream is = new FileInputStream("priv.p12");
            KeyStore keystore = KeyStore.getInstance("PKCS12");
            keystore.load(is, "".toCharArray());
            System.out.println("Successfully loaded");
    
    
            String keyAlias = "1";
    
    
            PrivateKey key = (PrivateKey)keystore.getKey(keyAlias, "".toCharArray());
    
            System.out.println("key "+Base64.encodeBase64String(key.getEncoded()));
            Cipher rsaDecryptCipher;
            rsaDecryptCipher = Cipher.getInstance("RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING");
            rsaDecryptCipher.init(Cipher.DECRYPT_MODE, key);
            final byte[] plainText = rsaDecryptCipher.doFinal(Base64.decodeBase64(base64String));
    
            System.out.println("Plain   : " + new String(plainText));
    
        }
    
    1. 我确保使用相同的密钥对,而不是不同的私钥
    2. 确保加密和解密“SHA256”中使用的哈希算法相同

    我可能遗漏了什么,如果有人需要更多细节,请告诉我。感谢您的帮助!!。谢谢

    1 回复  |  直到 7 年前
        1
  •  1
  •   Community CDub    3 年前

    OAEP使用两种哈希算法 :一个在标签上(fka参数),一个在遮罩生成功能(MGF1)内;这些可能不同。参见中的7.1.1和B.2.1 rfc8017

    我不知道Go代码是否设置了一个(和哪个)或两个,但Java对此做了什么 getInstance 这取决于您使用的提供者,而这又至少部分取决于您使用的Java实现。在Sun/Oracle和OpenJDK实现中默认配置的SunJCE提供程序只更改标签哈希,将MGF1保留为SHA1;BouncyCastle提供程序会同时更改这两个选项。我不知道IBM和Android在这里做什么。

    一旦你确定(或猜测)Go在做什么,你可以通过添加 .init 致电适当的 OAEPParameterSpec 和相关 MGF1ParameterSpec

    主要是被欺骗 OAEPwithMD5andMGF1Padding in node-rsa
    Breaking down RSA/ECB/OAEPWithSHA-256AndMGF1Padding
    (复制于 https://security.stackexchange.com/questions/97548/breaking-down-rsa-ecb-oaepwithsha-256andmgf1padding )