簡體   English   中英

獲得不同的加密結果 - RSA - Java 和 Openssl

[英]Getting different encryption results - RSA - Java and Openssl

When I encrypt a string of text with Java and Openssl - I am unable to decrypt the cipher (using Javascript Crypto Subtle) got from Openssl, however Java cipher is decrypted (with Crypto Subtle Web API JS) succesfully. 您能否查看並告知錯誤在哪里?

  1. 以下是 Base64 中由 JS Crypto Sublte API 生成的 RSA 公鑰和私鑰示例:

公鑰(RSA-OAEP、monulus 2048、hash SHA-256):

MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA8JhmO71HZ1vb8uxKhw6MM+ZvtTmc9Tw6AFpJVgXKiTjebj1SPdnxhdhJ5Bj15RN0rGNACXhAyUdn7zsp66/tmjNuC91L+9PvQBjDbXLsx7XUV9nIGJ3aYO5/qruVNXwyemf7wlwZVDF7oeZ8JUfjABTg7a7xui2WdXDHgvhTQdvQ9TS0NkX9xWAiDSn/HWfoEBC7TLeKeVjHsT7g1JnskGxfVhFrLfxQCxYZle4ebXP7dCPsff4WNNCxzBQtHHt8iEoZ0SVKBzS5zhdLHIdAIW4ELdnYsM7iTlWZO+kfWnlV2i13lAJobhxOAqwsg4OqkTsrx0KtWfZH40bNtFzx8wIDAQAB

私鑰(相同參數):

   MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDwmGY7vUdnW9vy7EqHDowz5m+1OZz1PDoAWklWBcqJON5uPVI92fGF2EnkGPXlE3SsY0AJeEDJR2fvOynrr+2aM24L3Uv70+9AGMNtcuzHtdRX2cgYndpg7n+qu5U1fDJ6Z/vCXBlUMXuh5nwlR+MAFODtrvG6LZZ1cMeC+FNB29D1NLQ2Rf3FYCINKf8dZ+gQELtMt4p5WMexPuDUmeyQbF9WEWst/FALFhmV7h5tc/t0I+x9/hY00LHMFC0ce3yIShnRJUoHNLnOF0sch0AhbgQt2diwzuJOVZk76R9aeVXaLXeUAmhuHE4CrCyDg6qROyvHQq1Z9kfjRs20XPHzAgMBAAECggEAPtCjPGyeFFu00LclfB5tt20t9CQ/GP3o7MelxvpLF0mMNT74VmKs/rNqE037ARxzxUBCa1aEn6hvd9O8DadIgw5zaFCWMoDyQYtVlqE/NaMA9hDLf7XS2qTaGyLPgX/UFAZLAkMWb9ddfncVKYybtR0+Xn/i56dYVYAk7spTvmkai5Q4Li5eEJqrRNse5fg/wiwDda/cWlEvlvfziAjU51gS/Y9ItUT8Z1g8A2NYfqgFVgBVb0qrtbP76TWPbeLZr1FXTMDB0MO+zuC+1lq48+CYqSJqi9a4GlW2gi0wkaQe3VIOsHipv82kSh20LczXiSKqF58F8m4whWqpa02rrQKBgQD6tbuFiY8fVXi44m1mFO7KDIVXFjuMca0+qXisVaUhG4q42fnlHN0kyuH2IFXNxHD+gE4MnvAUkXDkG1znaz8vM2tfQn6vSpU7OytwOt6UEMWm+112083nGMUy1Me/6rAJbBWfTAl0KXY9/Y/SuEL8u+W6Eas+eASUIe1DooI4xwKBgQD1rAfUXjuRH6WFnbITdG8B3WVZhRCx3YuQVE1UnHR8N6qfx6qKIricvKMSvtWAj0UiIbSA8DENyfMiyAbGpZ0cILxtdXZOtZFW9hfiOeLptnYKTJXOiGoju1prxpUNUKu/1kd7e0clxN75mooge8yFFA6il43wYhhwO2si+FYJdQKBgQDL+1TpX3StX9NrSf8MkXd/uRQ8OQCWUl9MnoJqZPyHpWsG34Ms4IElUFTs9n4Zfv0YdLgMGLzpXzRkw8ahG2c7NjDkPqvoX1xv5sJ++8bg3YyTQe1XoxjiMAsyQmGLSp2T7PbitvDyLFHiOg3surL2AsL00y9rEidXhwsOfohJPQKBgQCqhw4sQHjShIgNlmfMj06amcZG/FGZVPISbiH7cFp++tjp7duX5QAGc/4x/dsPUOOpDIJR2egC7UJiyzvA2aaTprmEtTs46VmIZmwvsQSsO+X1wjFeWlxqjxr1orNFudBt6dxWfzzkn6Iy2i203Jobac+61r5EtKLIDMaSUJTQHQKBgQDaNTfgakpyZBSp/Ydzu76qDKpzGuDqrLBnR/lui4DrSyUoOjNwaGlkU/B6USdaC/BGO7lI08HZU7FzutvXb1mKS+nUI7rKvSTN9NKUJF4MaBv9q40RViKkF9vbq2f1wMs2KUNc0ex2ZL+5BOBICJNHyVulKSxY54Z55L/H4FZmWw==


  1. 這是 Java 代碼,它接收公鑰作為 Base64 字符串並從它創建 PublicKey 實例。 然后我用這個密鑰加密一串文本並將密碼編碼為 Base64 字符串。

     String stringToEncrypt = "This is encrypted message;..". byte[] publicKeyBytes = Base64.getDecoder().decode("MIIBIjANBgkqhki.;.;"), Cipher cipher = Cipher,getInstance("RSA/ECB/OAEPPadding"), OAEPParameterSpec oaepParams = new OAEPParameterSpec("SHA-256". "MGF1". new MGF1ParameterSpec("SHA-256");PSource.PSpecified;DEFAULT). KeyFactory keyFactory = KeyFactory;getInstance("RSA"). PublicKey rsaPublicKey = keyFactory.generatePublic(new X509EncodedKeySpec(publicKeyBytes)), cipher,init(Cipher;ENCRYPT_MODE. rsaPublicKey.oaepParams). String cipherBytes = Base64.getEncoder();encodeToString(cipher.doFinal(stringToEncrypt.getBytes()));

    cipherBytes Base64 字符串隨后被下面的 JS Crypto Subtle 代碼成功解密:

  2. 第一個密鑰對生成代碼:

const keyPair = await window.crypto.subtle.generateKey(
            {
                name: "RSA-OAEP",
                modulusLength: 2048,
                publicExponent: new Uint8Array([1, 0, 1]),
                hash: "SHA-256"
            },
            true,
            ["encrypt", "decrypt"]
        )

導入私鑰 =

    return window.crypto.subtle
          .importKey("pkcs8", base64StringToArrayBuffer(privateKeyInPem), {
              name: "RSA-OAEP",
              hash: "SHA-256",
          }, true, ["decrypt"]).then(key=>{
              return key;
          })

然后解密密碼

        const dec = new TextDecoder();

        function str2ab(str: any) {
            const buf = new ArrayBuffer(str.length);
            const bufView = new Uint8Array(buf);
            for (let i = 0, strLen = str.length; i < strLen; i++) {
                bufView[i] = str.charCodeAt(i);
            }

            return buf;
        }

        console.log('cipher: '+cipher)
        return window.crypto.subtle.decrypt({
                name: "RSA-OAEP",
            },
            privateKey,
            str2ab(window.atob(cipher))
        ).then(result=>{
            console.log('DECRYPTED MSG:'+dec.decode(result));
        })


但問題是當我嘗試從 openssl 解密密碼時 - 它不起作用。 這是我使用的 Openssl 命令:

OpenSSL> rsautl -encrypt -pubin -keyform DER -inkey publicKey.der -oaep -in input.txt -out out.bin

我正在使用相同的公鑰,只是從 Base64 字符串轉換為 DER 格式(使用 Java 將 Base64 字符串密鑰轉換為 DER - 1. 解碼 base64 字符串 -> 字節 []-> 將每個字節寫入文件)

最后 Openssl 操作將二進制數據從 out.bin 轉換為 Base64 字符串

OpenSSL> enc -A -base64 -in out.bin -out base64.txt

rsautl一成不變地使用 SHA1 作為 OAEP 摘要,請參見此處 由於您在 WebCrypto 代碼中應用了 SHA256,因此您必須改用pkeyutl ,它允許指定摘要:

openssl pkeyutl -in plaintext.txt -out ciphertext.bin -encrypt -keyform DER -pubin -inkey spki.der -pkeyopt rsa_padding_mode:oaep -pkeyopt rsa_oaep_md:sha256 -pkeyopt rsa_mgf1_md:sha256 

可以使用 WebCrypto 代碼解密以這種方式生成的密文:

 (async () => { // your private key var privateKeyInPem = "MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDwmGY7vUdnW9vy7EqHDowz5m+1OZz1PDoAWklWBcqJON5uPVI92fGF2EnkGPXlE3SsY0AJeEDJR2fvOynrr+2aM24L3Uv70+9AGMNtcuzHtdRX2cgYndpg7n+qu5U1fDJ6Z/vCXBlUMXuh5nwlR+MAFODtrvG6LZZ1cMeC+FNB29D1NLQ2Rf3FYCINKf8dZ+gQELtMt4p5WMexPuDUmeyQbF9WEWst/FALFhmV7h5tc/t0I+x9/hY00LHMFC0ce3yIShnRJUoHNLnOF0sch0AhbgQt2diwzuJOVZk76R9aeVXaLXeUAmhuHE4CrCyDg6qROyvHQq1Z9kfjRs20XPHzAgMBAAECggEAPtCjPGyeFFu00LclfB5tt20t9CQ/GP3o7MelxvpLF0mMNT74VmKs/rNqE037ARxzxUBCa1aEn6hvd9O8DadIgw5zaFCWMoDyQYtVlqE/NaMA9hDLf7XS2qTaGyLPgX/UFAZLAkMWb9ddfncVKYybtR0+Xn/i56dYVYAk7spTvmkai5Q4Li5eEJqrRNse5fg/wiwDda/cWlEvlvfziAjU51gS/Y9ItUT8Z1g8A2NYfqgFVgBVb0qrtbP76TWPbeLZr1FXTMDB0MO+zuC+1lq48+CYqSJqi9a4GlW2gi0wkaQe3VIOsHipv82kSh20LczXiSKqF58F8m4whWqpa02rrQKBgQD6tbuFiY8fVXi44m1mFO7KDIVXFjuMca0+qXisVaUhG4q42fnlHN0kyuH2IFXNxHD+gE4MnvAUkXDkG1znaz8vM2tfQn6vSpU7OytwOt6UEMWm+112083nGMUy1Me/6rAJbBWfTAl0KXY9/Y/SuEL8u+W6Eas+eASUIe1DooI4xwKBgQD1rAfUXjuRH6WFnbITdG8B3WVZhRCx3YuQVE1UnHR8N6qfx6qKIricvKMSvtWAj0UiIbSA8DENyfMiyAbGpZ0cILxtdXZOtZFW9hfiOeLptnYKTJXOiGoju1prxpUNUKu/1kd7e0clxN75mooge8yFFA6il43wYhhwO2si+FYJdQKBgQDL+1TpX3StX9NrSf8MkXd/uRQ8OQCWUl9MnoJqZPyHpWsG34Ms4IElUFTs9n4Zfv0YdLgMGLzpXzRkw8ahG2c7NjDkPqvoX1xv5sJ++8bg3YyTQe1XoxjiMAsyQmGLSp2T7PbitvDyLFHiOg3surL2AsL00y9rEidXhwsOfohJPQKBgQCqhw4sQHjShIgNlmfMj06amcZG/FGZVPISbiH7cFp++tjp7duX5QAGc/4x/dsPUOOpDIJR2egC7UJiyzvA2aaTprmEtTs46VmIZmwvsQSsO+X1wjFeWlxqjxr1orNFudBt6dxWfzzkn6Iy2i203Jobac+61r5EtKLIDMaSUJTQHQKBgQDaNTfgakpyZBSp/Ydzu76qDKpzGuDqrLBnR/lui4DrSyUoOjNwaGlkU/B6USdaC/BGO7lI08HZU7FzutvXb1mKS+nUI7rKvSTN9NKUJF4MaBv9q40RViKkF9vbq2f1wMs2KUNc0ex2ZL+5BOBICJNHyVulKSxY54Z55L/H4FZmWw=="; var privateKey = await window.crypto.subtle.importKey("pkcs8", base64StringToArrayBuffer(privateKeyInPem), {name: "RSA-OAEP", hash: "SHA-256"}, true, ["decrypt"]); console.log(privateKey); // Base64 encoded ciphertext from openssl pkeyutl var cipher = "V2QWzwoOHPAlKhGqv0fDSv+lSPytBW4tTxVVJgneyvfIqTDvllhbZJzUAszdAC0IEow+YgbIWHyIBCw9YVS+EDZ3jbuIU97nx5NxAimiUFKvUmHE8p3oP6AP/etJhGQGC+fMiTbhmGn5FQhMnH/2lVei3yJypXWbgI6ONRmncYalq73q7VGelFUSubuPWQA3bKzuIOSorpQFy9sGIMDvW+YOMLrClVmUujVrEXrdsIbvzSb6hooKHbwjOaAmN4XRw0sr+YaF3n2PwazpLSvJmuugF26GxhmJAMmNViUvvsN+ycpJZdyRKNehQGqmahpC0XXihZ9dsHEH7vIDDmPAZQ=="; console.log('cipher: '+cipher) // successfull decryption var decrypted = await window.crypto.subtle.decrypt({name: "RSA-OAEP"}, privateKey, str2ab(window.atob(cipher))); const dec = new TextDecoder(); console.log('DECRYPTED MSG:' + dec.decode(decrypted)); })(); function base64StringToArrayBuffer(base64String){ return Uint8Array.from(window.atob(base64String), c => c.charCodeAt(0)); } function str2ab(str) { const buf = new ArrayBuffer(str.length); const bufView = new Uint8Array(buf); for (let i = 0, strLen = str.length; i < strLen; i++) { bufView[i] = str.charCodeAt(i); } return buf; }


為了完整性:在 OAEP 的上下文中,有兩個摘要需要指定,內容摘要和 MGF1 摘要。 pkeyutl允許獨立設置兩者。 如果兩個摘要相同(通常是這種情況),則通過rsa_oaep_md僅設置內容摘要就足夠了,即只要沒有通過rsa_mgf1_md顯式設置其他摘要,MGF1 摘要就隱式具有相同的值。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM