세부 사항에 너무 많이 들어가기 전에 내가 수행하려는 고차원적인 작업은 JavaScript의 일부 데이터를 암호화하여 웹 서버에서 C#으로 암호화 된 데이터를 해독합니다. 문제가있는 부분은 C#에서 데이터를 해독하는 것입니다. 나는이 같은 자바 스크립트에서 일부 데이터를 암호화하고있어RSA-OAEP를 사용하여 JavaScript에서 암호화 된 C#의 데이터 암호 해독시 OAEP 패딩 오류
는 (I는 불필요한 코드를 제거) :
// https://github.com/diafygi/webcrypto-examples#rsa-oaep---encrypt
window.crypto.subtle.encrypt(
{
name: "RSA-OAEP"
},
publicKey,
data
)
.then(function (encrypted) {
// ...
});
내가 그래서 (내가 실제로하지 원하는 점에 유의처럼 자바 스크립트에서 암호를 해독 할 수 있음을 확인
이렇게,하지만 난) 데이터를 해독 할 수 있다는 것을 증명하기 위해 그것을했다 : 간단하게하기 위해, 그 코드 샘플은 "밥"의 이전에 암호화 된 값을 해독한다
function decryptValue() {
// Base64 decode the encrypted data for the value "Bob".
var data = base64Decode("CthOUMzRdtSwo+4twgtjCA674G3UosWypUZv5E7uxG7GqYPiIJ+E+Uq7vbElp/bahB1fJrgq1qbdMrUZnSypVqBwYnccSxwablO15OOXl9Rn1e7w9V9fuMxtUqvhn+YZezk1623Qd7f5XTYjf6POwixtrgfZtdA+qh00ktKiVBpQKNG/bxhV94fK9+hb+qnzPmXilr9QF5rSQTd4hYHmYcR2ljVCDDZMV3tCVUTecWjS5HbOA1254ve/q3ulBLoPQTE58g7FwDQUZnd7XBdRSwYnrBWTJh8nmJ0PDfn+mCTGEI86S7HtoFYsE+Hezd24Z523phGEVrdMC9Ob1LlXEA==");
// Get private key.
var keyPromise = importPrivateKey();
return keyPromise.then(function (privateKey) {
// Decrypt the value.
return window.crypto.subtle.decrypt(
{
name: "RSA-OAEP"
},
privateKey,
data
)
.then(function (decrypted) {
// Log the decrypted value to the console.
console.log(arrayBufferToString(decrypted));
});
});
}
. 이것은 잘 작동합니다. 나는 C#에서 값을 해독 할 때
이 문제가 발생합니다
public static string Decrypt()
{
// The encrypted and base64 encoded value for "Bob".
var encryptedValue = "CthOUMzRdtSwo+4twgtjCA674G3UosWypUZv5E7uxG7GqYPiIJ+E+Uq7vbElp/bahB1fJrgq1qbdMrUZnSypVqBwYnccSxwablO15OOXl9Rn1e7w9V9fuMxtUqvhn+YZezk1623Qd7f5XTYjf6POwixtrgfZtdA+qh00ktKiVBpQKNG/bxhV94fK9+hb+qnzPmXilr9QF5rSQTd4hYHmYcR2ljVCDDZMV3tCVUTecWjS5HbOA1254ve/q3ulBLoPQTE58g7FwDQUZnd7XBdRSwYnrBWTJh8nmJ0PDfn+mCTGEI86S7HtoFYsE+Hezd24Z523phGEVrdMC9Ob1LlXEA==";
// Assuming RSA-OAEP.
var doOaep = true;
// Setup encryption algorithm.
var provider = GetPrivateKey();
// Decrypt value.
var encryptedData = Convert.FromBase64String(encryptedValue);
// This line throws an error: "Error occurred while decoding OAEP padding."
var decryptedData = provider.Decrypt(encryptedData, doOaep);
var decryptedText = Encoding.Unicode.GetString(decryptedData);
// Return decrypted text.
return decryptedText;
}
provider.Decrypt(encryptedData, doOaep)
가의 메시지와 함께 오류가 발생합니다 말한다 라인 "OAEP 패딩을 디코딩하는 동안 오류가 발생했습니다." 스택 추적 :
Error occurred while decoding OAEP padding.
at System.Security.Cryptography.RSACryptoServiceProvider.DecryptKey(SafeKeyHandle pKeyContext, Byte[] pbEncryptedKey, Int32 cbEncryptedKey, Boolean fOAEP, ObjectHandleOnStack ohRetDecryptedKey)
at System.Security.Cryptography.RSACryptoServiceProvider.Decrypt(Byte[] rgb, Boolean fOAEP)
가 C 번호의 값을 암호화하는 방식과 호환되지 않습니다. 이 접근법을 완전히 포기하고 다른 JavaScript 라이브러리에서 암호화를 시도하기 전에이 오류를 해결할 수있는 방법이 있습니까? https://www.codeproject.com/Articles/11479/RSA-Interoperability-between-JavaScript-and-RSACry
그것은 말합니다 : 자바 스크립트 코드에서
호환되지 않는 패딩 방식은 "나쁜 데이터를 생성 추가로 상황에 대한
,이 오류가이 문서에 언급 된 어떤 관련이 추측하고있다 "예외는 서버 측에서 발생합니다.
는자바 스크립트 코드는 따라서 첫 번째의 PKCS # 1 v1.5에 패딩이고 다른 패딩 OAEP (1 V2 PKCS 번호)이고, 두 심 닷넷 RSA 구현에 사용 방식 중 하나를 구현할 필요가있다.
정확한 예외는 표시되지 않지만 어쩌면 해당 문서가 작성된 이후로 오류 메시지가 변경되었을 수 있습니다. 어쨌든이 글에서 말하는 것은 JavaScript가 암호화하는 방식이 C#이 해독하는 방식 (즉, C#의 패딩 요구 사항 때문)과 호환되지 않는다는 것을 암시하는 것처럼 보입니다.
내가 빠진 것이 있나요? 몇 가지 매개 변수 또는 C#에서 작동하는 암호화 및 암호 해독에서 작동하도록하는 간단한 방법이 있습니까? 아마도 JavaScript가 암호화하는 방식과 호환되는 방식으로 해독하는 C# 라이브러리가 있을까요?
다음은 JavaScript가 올바르게 해독되는 일부 예입니다 (일부 브라우저에서만 작동 함).아마) IE에서 작동하지 않을 :
function decryptValue() {
// Base64 decode the encrypted data for the value "Bob".
var data = base64Decode("CthOUMzRdtSwo+4twgtjCA674G3UosWypUZv5E7uxG7GqYPiIJ+E+Uq7vbElp/bahB1fJrgq1qbdMrUZnSypVqBwYnccSxwablO15OOXl9Rn1e7w9V9fuMxtUqvhn+YZezk1623Qd7f5XTYjf6POwixtrgfZtdA+qh00ktKiVBpQKNG/bxhV94fK9+hb+qnzPmXilr9QF5rSQTd4hYHmYcR2ljVCDDZMV3tCVUTecWjS5HbOA1254ve/q3ulBLoPQTE58g7FwDQUZnd7XBdRSwYnrBWTJh8nmJ0PDfn+mCTGEI86S7HtoFYsE+Hezd24Z523phGEVrdMC9Ob1LlXEA==");
// Get private key.
var keyPromise = importPrivateKey();
return keyPromise.then(function (privateKey) {
// Decrypt the value.
return window.crypto.subtle.decrypt(
{
name: "RSA-OAEP"
},
privateKey,
data
)
.then(function (decrypted) {
// Log the decrypted value to the console.
console.log("Decrypted value: " + arrayBufferToString(decrypted));
});
});
}
function importPrivateKey() {
var rawKey = {
"alg": "RSA-OAEP-256",
"d": "E4KDwgxy7jFrqeXqKjxPTGOdbEoZ2aWj5qcZhUJcnr9Qh_jg_grkgpHVwEbQifTxsipXTiR3_ygspI4XFoeV-wDVfWqWCVR3_bHChF9PW8Ak1x_dBSS28BMs8PdthI1pDbpqPhmMcF4riHCtNo1M1v8cLdeaiqiXitNVBkaTePsDiucfwOy1rgxwBqAL1CNJhP8oRiYkxD-gfE_EapWuXY9-wF9O-lXPLSTKWgMmmVxSmhUP-Uqk7cJ24UH9C7W7hnSQU4pkfD5XHx3_2WO2GMKKZcqz39wJUrQzrIO7539SYsQ3rEe4aMJyL4U-Ib4_purzVS0DRjzGxK8chT2guQ",
"dp": "kibhWHk1R6yBlhZbjIrNl9beAkyV5vtFsj_F0ixbIITzjSqI_td71sWjKQvJ2rR7hu5DYTZ4p3XwBeQ2jpYQV-y5uh4v7rGngh-0GHuHqMiUQnejgYGcHgng4iCM4e3aTO7QUlP8jqRfxw6xpfNTjrVbAL8LtdCG21vmqOiLkXE",
"dq": "qLF9x-zKfaXlLsNgBQ1ZnaQexrnJRqrRh9JSU85fCNy5mmpKWAUbCHB-59CGAId8wMAnAyEpjcBOKNTqWSlNzp84xeUHcyPI-Dt4Yp_Y_dXjGAYntALSJs4qeF2rk55MSpiSD_KSU4DknX_E_G2rFMY7AZOSwi1D8YcNmj5okTE",
"e": "AQAB",
"ext": true,
"key_ops": [
"decrypt"
],
"kty": "RSA",
"n": "oQeTwOlTc6rIb2kddwIOc0Ywslc7YzJSRZd_PegW7T3nO3DqCI5kp5EJmnGP8JJ9sbyVYyAHFLZQtMP69UspZFn__fBk2LTp2QdqBSMHbObENcSiG2FH-pZSwCaj3Pvy-qvTjnkxxN-3OE6oB8EcX5ekZwCZzAxazbVXctY_hCcaTWG7ugwc_ZyvhsdE7wa3pnTfXYHWXcDDT8FTpYl62aqWsEIUAJSkgmQ9zce0RiDUjBJyJEM9P0ihp1Ab8BD88pEM22-PXfiOesRzp5yOsjzI3kdr5KPsshstneJEGHYae5GZXLUpnVMRY1TCFFLbkPwK6oVkRaVU1RvK9ssO3Q",
"p": "2TTEToB4AuPIPPpg3yTyBlGb_m-f4r-TxpU96ConV2p696_4QI6jlPWwgcC9Vdma_Da43AGuyLzIptgkzF8nSjV80VwwDKQ1YkFPc6ZqB2isvExuieSP6_jLlB-fCyCLqtTxpPm2VcK16Pqm0s5T0QGH6cQjjm1r2Ww1wuaiQbk",
"q": "vcpFwkZKZ3hx3FpHgy3ScuuTRSPO2ge8TE8UMJdCrEnpftAeYuVYrJqnxfzKgyl02OijAUi1eozJxj_lM5McxrKZEEAvo6e8wtzl2hnkUh-KWoBJ8ii0VJcu6U5vs4pcv-lYBPFC6fzoGnUw8LNWMxb5ejgYbLUWp10BbfkWGEU",
"qi": "Mza7JYleki7BvmD3dX5CO2nkD3mBGz4_0P_aoWyHEkWu4p5XWillaRVWyLnQEubLvAduUCr-lhfNmzdUhHecpE438_LQNtKRyOq9zkvjsMOGDmbkKpZ7-aTSshax6KNlYOWdOkadjuLtRExCmwbzu5lgI4NwacxSs5MfjHMrTCo"
};
return window.crypto.subtle.importKey(
"jwk",
rawKey,
{
name: "RSA-OAEP",
hash: { name: "SHA-256" }
},
true,
["decrypt"]
);
}
function arrayBufferToString(buffer) {
var result = '';
var bytes = new Uint8Array(buffer);
for (var i = 0; i < bytes.length; i++) {
result += String.fromCharCode(bytes[i]);
}
return result;
}
// Decodes a base64 encoded string into an ArrayBuffer.
// https://stackoverflow.com/a/36378903/2052963
function base64Decode(base64) {
var binary_string = window.atob(base64);
return stringToArrayBuffer(binary_string);
}
// Converts a string to an ArrayBuffer.
function stringToArrayBuffer(value) {
var bytes = new Uint8Array(value.length);
for (var i = 0; i < value.length; i++) {
bytes[i] = value.charCodeAt(i);
}
return bytes.buffer;
}
decryptValue();
private static RSACryptoServiceProvider GetPrivateKey()
{
RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
RSAParameters RSAparams = new RSAParameters();
RSAparams.Modulus = Base64UrlDecode("oQeTwOlTc6rIb2kddwIOc0Ywslc7YzJSRZd_PegW7T3nO3DqCI5kp5EJmnGP8JJ9sbyVYyAHFLZQtMP69UspZFn__fBk2LTp2QdqBSMHbObENcSiG2FH-pZSwCaj3Pvy-qvTjnkxxN-3OE6oB8EcX5ekZwCZzAxazbVXctY_hCcaTWG7ugwc_ZyvhsdE7wa3pnTfXYHWXcDDT8FTpYl62aqWsEIUAJSkgmQ9zce0RiDUjBJyJEM9P0ihp1Ab8BD88pEM22-PXfiOesRzp5yOsjzI3kdr5KPsshstneJEGHYae5GZXLUpnVMRY1TCFFLbkPwK6oVkRaVU1RvK9ssO3Q");
RSAparams.Exponent = Base64UrlDecode("AQAB");
RSAparams.D = Base64UrlDecode("E4KDwgxy7jFrqeXqKjxPTGOdbEoZ2aWj5qcZhUJcnr9Qh_jg_grkgpHVwEbQifTxsipXTiR3_ygspI4XFoeV-wDVfWqWCVR3_bHChF9PW8Ak1x_dBSS28BMs8PdthI1pDbpqPhmMcF4riHCtNo1M1v8cLdeaiqiXitNVBkaTePsDiucfwOy1rgxwBqAL1CNJhP8oRiYkxD-gfE_EapWuXY9-wF9O-lXPLSTKWgMmmVxSmhUP-Uqk7cJ24UH9C7W7hnSQU4pkfD5XHx3_2WO2GMKKZcqz39wJUrQzrIO7539SYsQ3rEe4aMJyL4U-Ib4_purzVS0DRjzGxK8chT2guQ");
RSAparams.P = Base64UrlDecode("2TTEToB4AuPIPPpg3yTyBlGb_m-f4r-TxpU96ConV2p696_4QI6jlPWwgcC9Vdma_Da43AGuyLzIptgkzF8nSjV80VwwDKQ1YkFPc6ZqB2isvExuieSP6_jLlB-fCyCLqtTxpPm2VcK16Pqm0s5T0QGH6cQjjm1r2Ww1wuaiQbk");
RSAparams.Q = Base64UrlDecode("vcpFwkZKZ3hx3FpHgy3ScuuTRSPO2ge8TE8UMJdCrEnpftAeYuVYrJqnxfzKgyl02OijAUi1eozJxj_lM5McxrKZEEAvo6e8wtzl2hnkUh-KWoBJ8ii0VJcu6U5vs4pcv-lYBPFC6fzoGnUw8LNWMxb5ejgYbLUWp10BbfkWGEU");
RSAparams.DP = Base64UrlDecode("kibhWHk1R6yBlhZbjIrNl9beAkyV5vtFsj_F0ixbIITzjSqI_td71sWjKQvJ2rR7hu5DYTZ4p3XwBeQ2jpYQV-y5uh4v7rGngh-0GHuHqMiUQnejgYGcHgng4iCM4e3aTO7QUlP8jqRfxw6xpfNTjrVbAL8LtdCG21vmqOiLkXE");
RSAparams.DQ = Base64UrlDecode("qLF9x-zKfaXlLsNgBQ1ZnaQexrnJRqrRh9JSU85fCNy5mmpKWAUbCHB-59CGAId8wMAnAyEpjcBOKNTqWSlNzp84xeUHcyPI-Dt4Yp_Y_dXjGAYntALSJs4qeF2rk55MSpiSD_KSU4DknX_E_G2rFMY7AZOSwi1D8YcNmj5okTE");
RSAparams.InverseQ = Base64UrlDecode("Mza7JYleki7BvmD3dX5CO2nkD3mBGz4_0P_aoWyHEkWu4p5XWillaRVWyLnQEubLvAduUCr-lhfNmzdUhHecpE438_LQNtKRyOq9zkvjsMOGDmbkKpZ7-aTSshax6KNlYOWdOkadjuLtRExCmwbzu5lgI4NwacxSs5MfjHMrTCo");
RSA.ImportParameters(RSAparams);
return RSA;
}
// From the PDF here: https://www.rfc-editor.org/info/rfc7515
// Also see: https://auth0.com/docs/jwks
public static byte[] Base64UrlDecode(string arg)
{
string s = arg;
s = s.Replace('-', '+'); // 62nd char of encoding
s = s.Replace('_', '/'); // 63rd char of encoding
switch (s.Length % 4) // Pad with trailing '='s
{
case 0: break; // No pad chars in this case
case 2: s += "=="; break; // Two pad chars
case 3: s += "="; break; // One pad char
default:
throw new System.Exception(
"Illegal base64url string!");
}
return Convert.FromBase64String(s); // Standard base64 decoder
}
나는 당신이 C#으로해야하는 것은 자바의 RSA/ECB/OAEPWithSHA-256AndMGF1Padding과 동일한 경우는 잘 모르겠지만, 만약 그렇다면, 당신이 시도하는 것이 좋습니다 https://github.com/digitalbazaar/forge #rsa. 이 경우 WebCrypto 대신 JavaScript에서 Forge를 사용할 수 있습니다. – Darlesson
자바 스크립트는 SHA-256을 해시 함수 및 MGF1 함수로 사용하여 RSA OAEP로 암호화됩니다. .NET은 단순히이를 지원하지 않습니다. 오라클 자바는 Bouncycastle 자바와 C# 라이브러리를 사용합니다. –
@JamesKPolk 정보를 제공해 주셔서 감사합니다. 그것이 "MGF1"이라는 용어를 처음 들었습니다. Bouncy Castle for C#을 사용하면 암호 해독이 작동한다고 생각합니까? –