javascript - 尝试通过 Steam 身份验证 : stumped with RSA ecnryption (js to python)

标签 javascript python encryption cryptography rsa

我正在尝试通过 steam auth here 。我困惑的地方是使用公钥的 RSA 密码加密。要编码的参数可以从 here 接收。我用来加密密码的代码是:

import base64
from Crypto.PublicKey import RSA
mod = long(publickey_mod, 16)
exp = long(publickey_exp, 16)
rsa = RSA.construct((mod, exp))
encrypted_password = rsa.encrypt(password, '')[0]
encrypted_password = base64.b64encode(encrypted_password)

这是 RSA.js:

var RSAPublicKey = function($modulus_hex, $encryptionExponent_hex) {
    this.modulus = new BigInteger( $modulus_hex, 16);
    this.encryptionExponent = new BigInteger( $encryptionExponent_hex, 16);
}

var Base64 = {
    base64: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
    encode: function($input) {
        if (!$input) {
            return false;
        }
        var $output = "";
        var $chr1, $chr2, $chr3;
        var $enc1, $enc2, $enc3, $enc4;
        var $i = 0;
        do {
            $chr1 = $input.charCodeAt($i++);
            $chr2 = $input.charCodeAt($i++);
            $chr3 = $input.charCodeAt($i++);
            $enc1 = $chr1 >> 2;
            $enc2 = (($chr1 & 3) << 4) | ($chr2 >> 4);
            $enc3 = (($chr2 & 15) << 2) | ($chr3 >> 6);
            $enc4 = $chr3 & 63;
            if (isNaN($chr2)) $enc3 = $enc4 = 64;
            else if (isNaN($chr3)) $enc4 = 64;
            $output += this.base64.charAt($enc1) + this.base64.charAt($enc2) + this.base64.charAt($enc3) + this.base64.charAt($enc4);
        } while ($i < $input.length);
        return $output;
    },
    decode: function($input) {
        if(!$input) return false;
        $input = $input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
        var $output = "";
        var $enc1, $enc2, $enc3, $enc4;
        var $i = 0;
        do {
            $enc1 = this.base64.indexOf($input.charAt($i++));
            $enc2 = this.base64.indexOf($input.charAt($i++));
            $enc3 = this.base64.indexOf($input.charAt($i++));
            $enc4 = this.base64.indexOf($input.charAt($i++));
            $output += String.fromCharCode(($enc1 << 2) | ($enc2 >> 4));
            if ($enc3 != 64) $output += String.fromCharCode((($enc2 & 15) << 4) | ($enc3 >> 2));
            if ($enc4 != 64) $output += String.fromCharCode((($enc3 & 3) << 6) | $enc4);
        } while ($i < $input.length);
        return $output; 
    }
};

var Hex = {
    hex: "0123456789abcdef",
    encode: function($input) {
        if(!$input) return false;
        var $output = "";
        var $k;
        var $i = 0;
        do {
            $k = $input.charCodeAt($i++);
            $output += this.hex.charAt(($k >> 4) &0xf) + this.hex.charAt($k & 0xf);
        } while ($i < $input.length);
        return $output;
    },
    decode: function($input) {
        if(!$input) return false;
        $input = $input.replace(/[^0-9abcdef]/g, "");
        var $output = "";
        var $i = 0;
        do {
            $output += String.fromCharCode(((this.hex.indexOf($input.charAt($i++)) << 4) & 0xf0) | (this.hex.indexOf($input.charAt($i++)) & 0xf));
        } while ($i < $input.length);
        return $output;
    }
};

var RSA = {

    getPublicKey: function( $modulus_hex, $exponent_hex ) {
        return new RSAPublicKey( $modulus_hex, $exponent_hex );
    },

    encrypt: function($data, $pubkey) {
        if (!$pubkey) return false;
        $data = this.pkcs1pad2($data,($pubkey.modulus.bitLength()+7)>>3);
        if(!$data) return false;
        $data = $data.modPowInt($pubkey.encryptionExponent, $pubkey.modulus);
        if(!$data) return false;
        $data = $data.toString(16);
        return Base64.encode(Hex.decode($data));
    },

    pkcs1pad2: function($data, $keysize) {
        if($keysize < $data.length + 11)
            return null;
        var $buffer = [];
        var $i = $data.length - 1;
        while($i >= 0 && $keysize > 0)
            $buffer[--$keysize] = $data.charCodeAt($i--);
        $buffer[--$keysize] = 0;
        while($keysize > 2)
            $buffer[--$keysize] = Math.floor(Math.random()*254) + 1;
        $buffer[--$keysize] = 2;
        $buffer[--$keysize] = 0;
        return new BigInteger($buffer);
    }
}

这是来自 Steam 网站的 JS 代码:

var pubKey = RSA.getPublicKey( results.publickey_mod, results.publickey_exp );
var encryptedPassword = RSA.encrypt( password, pubKey );

我想我必须使用 Crypto.PKCS1_v1_5 而不是 Crypto.PublicKey.RSA.encrypt 因为该函数恰好对应于名称“pkcs1pad2”,但我不知道在哪里将 publickey_exp 放入其中以及如何导入现有 key

最佳答案

正如您所怀疑的,您应该使用 Crypto.Cipher.PKCS1_v1_5,如以下代码片段所示:

import base64
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5
mod = long(publickey_mod, 16)
exp = long(publickey_exp, 16)
rsa_key = RSA.construct((mod, exp))
rsa = PKCS115_Cipher(rsa_key)
encrypted_password = rsa.encrypt(password)
encrypted_password = base64.b64encode(encrypted_password)

关于javascript - 尝试通过 Steam 身份验证 : stumped with RSA ecnryption (js to python),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26822354/

相关文章:

c# - 如何在 C# 中实现三重 DES(完整示例)

javascript - Chrome 首次双击

javascript - 根据 MIN 和 MAX 数组值更改 DIV 颜色背景?

python使用测试分数列表

encryption - JWT - 什么算法 "harder to hack"

python - python 的诅咒。将 ansi 颜色代码从标准输入转换为 curses 输出

javascript - 在双引号内获取值,前面有一个单词

javascript - jQuery:同时将函数应用于元素

python - kivy 进口出了什么问题?

python - 在 Pandas 数据框中选择行时如何保持顺序?