[英]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. 您能否查看並告知錯誤在哪里?
公鑰(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==
這是 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 代碼成功解密:
第一個密鑰對生成代碼:
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.