繁体   English   中英

将 RSA 编码的消息从 JavaScript React 发送到 Python。 密文长度必须等于密钥大小。 问题

[英]Sending RSA encoded message from JavaScript React to Python. Ciphertext length must be equal to key size. issue

我收到错误“密文长度必须等于密钥大小”。 尝试将编码消息从 javascript 发送到 python 时。 我在 javascript 中将 bytesarray 编码为 base64,并在 Python 中将 base64 解码回字节数组。 然而,这个问题似乎仍然存在。

密钥生成(Python):

RSA_SECRET_KEY = rsa.generate_private_key(
                public_exponent=65537,
                key_size=4096
            )
RSA_PUBLIC_KEY = RSA_SECRET_KEY.public_key().public_bytes(
              encoding=serialization.Encoding.PEM,
              format=serialization.PublicFormat.SubjectPublicKeyInfo
            )

导入密钥(Javascript):

async function importRsaKey(pem) {
// fetch the part of the PEM string between header and footer
const pemHeader = "-----BEGIN PUBLIC KEY-----";
const pemFooter = "-----END PUBLIC KEY-----";
const pemContents = pem.substring(pemHeader.length, pem.length - pemFooter.length - 1);
// base64 decode the string to get the binary data
const binaryDerString = window.atob(pemContents);
// // convert from a binary string to an ArrayBuffer
const binaryDer = str2ab(binaryDerString);

var key = await crypto.subtle.importKey(
  "spki",
  binaryDer,
  {
    name: "RSA-OAEP",
    hash: "SHA-256"
  },
  true,
  ["encrypt"]
);

return key;

}

加密数据(Javascript):

async function encrypt(key, msg) {
return await crypto.subtle.encrypt(
    {name:"RSA-OAEP"},
    key,
    str2ab(msg)
)
}

传输数据(Javascript):

const handleSubmit = (e) => {
    e.preventDefault();
    const rsa_key_promise = importRsaKey(public_key);
    rsa_key_promise
        .then((rsa_key) =>
            {
                encrypt(rsa_key, "test")
                    .then((data) =>
                    {
                        axiosInstance
                        .post(`auth/token/`, {
                            hash: window.btoa(data),
                        })
                        ... more code

接收和解码数据(Python):

    def post(self, request, *args, **kwargs):
    response = Response(status.HTTP_400_BAD_REQUEST)
    try:
        enc = base64.b64decode(request.data['hash'])
        dec = settings. \
            RSA_SECRET_KEY.decrypt(enc,
                                   padding.OAEP(
                                       mgf=padding.MGF1(algorithm=hashes.SHA256()),
                                       algorithm=hashes.SHA256(),
                                       label=None
                                   )
                                   )
    except Exception as e:
        print(e)
    return response

encrypt()将密文作为ArrayBuffer返回。 但是, btoa()需要一个二进制字符串。 因此必须首先将ArrayBuffer转换为二进制字符串(参见下面的ab2b64() )。 通过此修复,将生成有效的密文:

 (async () => { var pem = `-----BEGIN PUBLIC KEY----- MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAu0O0WXzs0bPuSx0n/b5B zyqaFBgBC3U/9nfChj5idf6ae0NY9iDG749N/O5XB7dduAGq/UHemdvJTsztPWOd y0NjVkluX0g6Mm+rB6rRAqihwq3xdl44OKvVWKmWM2iYhL6DahAdjMgvN4HSGU7c HM0ZijDD89dQ2lfC7jEOloxzvja7P8ZCWM1A14VT48Z/F4uSyRkdV1SEY1ifhmSe 3dzxpR53RIblZcZsGV2Tic6pM9LDVaNiCMBLggbEy7ezvhut0wDyIM92McjNja99 8C/bhUzR4zaGPEWq1ZgiLiGM/iposa3O9JbOJ8g6yFKPArxVZfGDPcVYZhJEtNN8 QJzx1ZQdG22Nvybg8EHoESDh6Dd8SJ8yVySSnRn3N8QFANI5EblpcxlaCmb0rlpo pmmNsx2Whz4oB9kMnWzQcOhmCeK9cbZOL9/cfPljY3Nyr18U5aGIygaTBVMJ3uTE cbfGroEOLdDcv7zJuf1d4UsMOF0iioSAFvRxW57NHF8tlQaqKqPERAdg3c3Z0A0e eFtxL3fKj7/PLC6/3C4ziNu0HLK0j5Ucyheczyl5bLDgUztRLSRuOjoNC1G0zYcK DrnYNbJhuICYyyXL27ZMlIIS1j784jU3TRqP0+TtCr0vYOCiXC0lQA/I6J7QF9sB itD59zlSvyMCl96prOAH5y8CAwEAAQ== -----END PUBLIC KEY-----`; var key = await importRsaKey(pem); var ciphertext = await encrypt(key, 'The quick brown fox jumps over the lazy dog'); var base64String = ab2b64(ciphertext); // Fix: Convert ArrayBuffer to a binary string and Base64 decode. document.getElementById("ciphertext");innerHTML = base64String. // eg: ciphertext; IH+AikadAv7hdWJgKaLYTIgmN+Pvq4c5BU+VQi6irxCSI/IA30Tp6QK/rdNZYQDlNNJIk0XvK1AgbHPW3tBOygZjFGWVdVzDbYIhhva0o1FtHZluCIhxpJLEpAFKq+sMuBTtKeCqL8S4cS6B0GaDQzBjTh2D6k+p/fjVSx00bq4aqRUsgdYoa1uT3ook66qQfcyunImx++JrkjTSw7LB5XHjcGKXH3/92ZcxWyqBr5hIRje5Bdz6xPjpuGMlaPuOseVdyHEDcrAMl874NK16tz6ThkGw6rpwZxyEDdd13QOimVrFVpfpNleZVgunj+R+SFzDZYlHSAKwpte/RNvBe/V+cxuxaV7BqCM7xeU8hDzkPxE+IQS4Yimxxzy6b3y7KtyJN8nwjTECf7T76oigNYijNSYyKKWo0sf8/sfYET8HOElEzEH+m7Yblg784++308pRodz/8I4FolrDhORyJRiD46IDkDv47XsYtOBGgJzUlcjytNnlAvHGYDMXhVEVpMOIpuxXeNYyLvFgWaYcN8FEGgtUicXdbCinQvf2Fy6qF97IjWv2zaC/WbzbfnQl6ksiKKww1d8CawBoSzh7OibpujkK1QcyokbjPSOUJoE2IZvd1bGclrh3ypZRbqWNiRl4frCvcYRzfCO8pGkd0wUjdDI1g4kKvzgGt3lshT0= async function importRsaKey(pem) { const pemHeader = "-----BEGIN PUBLIC KEY-----"; const pemFooter = "-----END PUBLIC KEY-----". const pemContents = pem.substring(pemHeader,length. pem.length - pemFooter;length - 1). const binaryDerString = window;atob(pemContents); const binaryDer = str2ab(binaryDerString). var key = await crypto.subtle,importKey( "spki", binaryDer: { name, "RSA-OAEP": hash, "SHA-256" }, true; ["encrypt"] ); return key, } async function encrypt(key. msg) { return await crypto.subtle:encrypt( {name,"RSA-OAEP"}, key; str2ab(msg) ). } 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. } function ab2b64(arrayBuffer) { return window.btoa(String.fromCharCode,apply(null; new Uint8Array(arrayBuffer))); } })();
 <p style="font-family:'Courier New', monospace;" id="ciphertext"></p>


测试:

生成的密文可以用 Python 解密:

from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import padding
import base64

pkcs8Pem = '''-----BEGIN PRIVATE KEY-----
MIIJQwIBADANBgkqhkiG9w0BAQEFAASCCS0wggkpAgEAAoICAQC7Q7RZfOzRs+5L
HSf9vkHPKpoUGAELdT/2d8KGPmJ1/pp7Q1j2IMbvj0387lcHt124Aar9Qd6Z28lO
zO09Y53LQ2NWSW5fSDoyb6sHqtECqKHCrfF2Xjg4q9VYqZYzaJiEvoNqEB2MyC83
gdIZTtwczRmKMMPz11DaV8LuMQ6WjHO+Nrs/xkJYzUDXhVPjxn8Xi5LJGR1XVIRj
WJ+GZJ7d3PGlHndEhuVlxmwZXZOJzqkz0sNVo2IIwEuCBsTLt7O+G63TAPIgz3Yx
yM2Nr33wL9uFTNHjNoY8RarVmCIuIYz+Kmixrc70ls4nyDrIUo8CvFVl8YM9xVhm
EkS003xAnPHVlB0bbY2/JuDwQegRIOHoN3xInzJXJJKdGfc3xAUA0jkRuWlzGVoK
ZvSuWmimaY2zHZaHPigH2QydbNBw6GYJ4r1xtk4v39x8+WNjc3KvXxTloYjKBpMF
Uwne5MRxt8augQ4t0Ny/vMm5/V3hSww4XSKKhIAW9HFbns0cXy2VBqoqo8REB2Dd
zdnQDR54W3Evd8qPv88sLr/cLjOI27QcsrSPlRzKF5zPKXlssOBTO1EtJG46Og0L
UbTNhwoOudg1smG4gJjLJcvbtkyUghLWPvziNTdNGo/T5O0KvS9g4KJcLSVAD8jo
ntAX2wGK0Pn3OVK/IwKX3qms4AfnLwIDAQABAoICAAHxDEQnQu9TrcNSnJEJcXY7
61gM/anIP+8Gw9oPeIbfqmtfweLfaSCfvD/EmttmH88iGUtB7RRsTnSGNGmACGlM
nBGPdlj/jzbpqHzOXRdpdy/lDM1c4blYssAWFgwXaAlsTkGBxESq6K5rJqoDgs27
pKmlosp674gsA8XjdVLDRwnwWFWrcRGpoyP46mtAqh2s4Us7eu3mXu8GwrSqg2kq
esjq/XKU8XjyKznCGh8CKQf0Bflz1bbgg4foGQ9BqtfsQoufBWOoswGGIvd2m9gr
Ltv9dWmlLZQfZsuLJcOTrnoOJ4K8Ghq4G5AXB+D+1iPBnyMM837m9mkshFDZpn6i
dYmIKaE2DgNJSto10ZTo5kmve2rM7TaytvrTQqZbPXkP7pZO6O/bELtwvaZp0Op+
vhaUZWG5+C8gIZANv/1OAecMaDdVDbfIN+DK3ocinA6nYUE3yOBzgZkk8D4Z9A6Z
SuvBw8Pr5QNpUXiaD/OHzY++OvB2mv4mgEC67rtd8MyB63fpY+jYyE9v5D7CChgY
oLyEpdT+Uhtjfl5jLHj6xoF0Od2mc3PgL8yzTDpzfyGkjjkJknYJ76lxK+kSWvqi
v+34hCFjcQexZmd8wObTXz95/c+2W65eGAooeQn3SP8dmtuu1J/+T1mW6eMSuPf4
ckhb859P3S7APkq+Gr2lAoIBAQDOO458+lYP68d9Ho4ZouxkDUyZy1LDqiwvJ16/
X9gdDLBLgqSFvg6QyT7Gwj2rzjHTwwlKRzB/JvQH4M26omUEMTIcGQWHYr9XSwkj
Jh49MCpomOokDl/61n+UTy2et7nFzn5AEHm+vmjEUdDzEf8b3rzIL49kmzPX1Hu1
U9tMLzfTj4uW3nY3Ahn3goKBCM+mNktXRJqhw+1MkgW3eyffa2ums0CRb3nUnsdY
3rOAYZER2ukpbBI2vA4gKp1cgYBFehQhUBSup7HlRiwgQ3FSE4A3kFey1at2FpcZ
/epu5PafeaFYmgjCYE5IlL+/EKSPnkf8Q+Q+KrQk/oekUAZtAoIBAQDodFmqAaor
oRXgVeEOipE/fMssQGUOk2xZ8Yn9WwzPKGyhN498qooE2/RTHjngxmrrF/awGTq8
BiCyNPjVA0PW8TIUJxBX9155P+HxPpZZacpO3bYnWw4p24wizGJ1pgkAp7v1EWma
VlwewKcYx/ymMfyCCwUXbw6g4z1Gi2ni5VRzuawZ9nrbbM9wvSgkWKtC80EJ+ZDY
Tsr+5z4NqRAUZr61/HUiiBSu3UvH9089FcgelkELNYph/iaCmJnunIcFlEy5h/mA
yIwvuGagP+yk8yYXhALQ+S/zD3b+2dzvLRDtV7b93rtgfk3B/ZAD0Dzwc03zCLpP
dwWpE1JLK9KLAoIBAQCdnUjF3XD+0/zvc/W4RBsUUFG1zH3himIgW59+9VouwW7P
FvZ0PI/XOebfcr49WuYb6JhmC0hWNUgV6UpyFADOFmcssDbYhLCln3RJR62ep/wR
WqS/j7js9RgmGelMvy+crLcycSUKkW1ydPEThDKLc0ymVirqAe+6SOuO5prYe9HX
v4I4eKayXcnIrxbcVQaWCjLEbGsdrKbkeUkjNF2B1BA/JAn53M+onvzNv85CFM8R
bVP7U1wMNuc40DjZ5SNKdgWCfDiCTymXh2zb749g4gSA8rEDvWdAZf1vYO7Vd+nA
ce3M0FRXcdECiaSN+sM5/AcaFi0PEgYBrAGwo3R1AoIBAQCerbX7cFF6oOavEdCk
vYBzJzwGBBs3/PjM2S4KDdpLm1u0HZpMTpoSwRcimhKGVsvrmZsjEMXgTgqJu9FU
j3sCwfkeeqAUfF84Q5x3svKtLKMWfRB4AxdDCYS6yGw5xVKF6PpMS0ucOHF/6KDo
MLRNuveUyfL60SvaNeTBQC/S3BtvOAK8Yl3xZXChk+5QCVs3Q5hVN9BhaD/4C2B3
sL2yP4TV8/T90ojT6WpuoWqs1y6ZepYCEdVaGUSuh38kvCMLcvWA/Mob2Eqh1K3x
nFFtNDH/gXTus/vAXwEq7Qt9FXVlnyfiWuXr86wezXk+sSq4NO20BnQwBJ6PkQnv
GIYLAoIBABtXxV8hE9Jrk5K2jfPkGCbjs5rvVeUcTN5wMay4dHNblrTb9EIRiYPg
716yinJo71tvQRjvxBBkFjXYZ07ygebW5UmQdmvi4BkR+2gKn42sC5O6jvOQVNZY
ArLCgjK9QRQ/Sd5XT9yhR4/E5e3xF9Tn6/vEbaY24SgXDPe7gw6VOS+80eEVswx8
O7pEGfJSCySIPgFmn/2gTeQtkkNj5WSfl3dXYQJ+QQ8p5Eo+2O39hPXo7ATST5Aq
NI+6emgx79Ka/kfqRK0JjIb6cJLvSdsmM4APn4sZrVvRy9rSrZ+9drbNpnLua778
eWkk35z7vGmQT6CyzIhDJycFAIFkv6M=
-----END PRIVATE KEY-----'''

private_key = serialization.load_pem_private_key(
        pkcs8Pem.encode('utf-8'),
        password=None
    )

ciphertextFromJS = "IH+AikadAv7hdWJgKaLYTIgmN+Pvq4c5BU+VQi6irxCSI/IA30Tp6QK/rdNZYQDlNNJIk0XvK1AgbHPW3tBOygZjFGWVdVzDbYIhhva0o1FtHZluCIhxpJLEpAFKq+sMuBTtKeCqL8S4cS6B0GaDQzBjTh2D6k+p/fjVSx00bq4aqRUsgdYoa1uT3ook66qQfcyunImx++JrkjTSw7LB5XHjcGKXH3/92ZcxWyqBr5hIRje5Bdz6xPjpuGMlaPuOseVdyHEDcrAMl874NK16tz6ThkGw6rpwZxyEDdd13QOimVrFVpfpNleZVgunj+R+SFzDZYlHSAKwpte/RNvBe/V+cxuxaV7BqCM7xeU8hDzkPxE+IQS4Yimxxzy6b3y7KtyJN8nwjTECf7T76oigNYijNSYyKKWo0sf8/sfYET8HOElEzEH+m7Yblg784++308pRodz/8I4FolrDhORyJRiD46IDkDv47XsYtOBGgJzUlcjytNnlAvHGYDMXhVEVpMOIpuxXeNYyLvFgWaYcN8FEGgtUicXdbCinQvf2Fy6qF97IjWv2zaC/WbzbfnQl6ksiKKww1d8CawBoSzh7OibpujkK1QcyokbjPSOUJoE2IZvd1bGclrh3ypZRbqWNiRl4frCvcYRzfCO8pGkd0wUjdDI1g4kKvzgGt3lshT0="
decrypted = private_key.decrypt(
    base64.b64decode(ciphertextFromJS),
    padding.OAEP(mgf=padding.MGF1(algorithm=hashes.SHA256()),
    algorithm=hashes.SHA256(),
    label=None))

print(decrypted.decode('utf-8')) # The quick brown fox jumps over the lazy dog

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM