javascript - Python 和 Node 之间的 Diffie-Hellman key 交换失败,并出现错误“提供的 key 太大”

标签 javascript python node.js cryptography diffie-hellman

我正在尝试使用最新的 Node 镜像( Node 版本:v13.10.1)在 Python 3.6 客户端和 Docker 容器中运行的 Node 服务器之间进行 DH key 交换。

我正在使用cryptography.io (2.9.2) python 客户端的库。客户端生成 DH key 并将十六进制编码的公钥发送到服务器。这是代码片段:

MODP15_HEX_PRIME = "ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf6955817183995497cea956ae515d2261898fa051015728e5a8aaac42dad33170d04507a33a85521abdf1cba64ecfb850458dbef0a8aea71575d060c7db3970f85a6e1e4c7abf5ae8cdb0933d71e8c94e04a25619dcee3d2261ad2ee6bf12ffa06d98a0864d87602733ec86a64521f2b18177b200cbbe117577a615d6c770988c0bad946e208e24fa074e5ab3143db5bfce0fd108e4b82d120a93ad2caffffffffffffffff"

...

def generate_DH_key():
    # MODP 15 -> generator=2, key_size=3072 https://www.rfc-editor.org/rfc/rfc3526.txt

    dh_parameters = dh.DHParameterNumbers(p=int(MODP15_HEX_PRIME, 16), g=2).parameters(backend=default_backend())

    client_private_dh_key = dh_parameters.generate_private_key()

    return client_private_dh_key

def send_signed_dh_key(client_public_dh_key):
    dh_key_bytes = client_public_dh_key.public_bytes(encoding=serialization.Encoding.DER,                                                     format=serialization.PublicFormat.SubjectPublicKeyInfo)

    response = requests.post(CRYPTO_ORACLE_URL, headers=CRYPTO_ORACLE_HEADERS,
                             data=json.dumps({'key': dh_key_bytes.hex()))

    if response.status_code != 200:
        print('Something went wrong sending client signed DH: ' + response.reason)
        exit(-1)

服务器使用加密库根据收到的 DH key 计算 secret 。这是代码片段:

const generateSecret=(clientDHPublic)=>{
    ...
    serverDH = crypto.getDiffieHellman("modp15");
    serverDH.generateKeys();

    console.log("server DH public:")
    console.log(serverDH.getPublicKey("hex"));
    console.log("client DH public:");
    console.log(clientDHPublic.toString("hex"));

    const dhSharedKey = serverDH.computeSecret(clientDHPublic);
    ...
}

我记录两个公钥只是为了比较结构,我不希望它们明显相同。 输出类似于:

server DH public:

8d367904f51854c3625ac85aec99f21b55963a583746302261f2299b9423f77a335607b2826d3d57695c16eb0b798720aed11d7d13704bcf1d68f05df9d29a00f374cc9b60095fb942be495a0f8a116d1e41761da7c1c403e174ea5715a5e1ff34cc9b409787fe48678141a095c26694c85ca52939b0c1b888f0a630ed8e1d8511cae7cf6ed6c3032cd32ab42743c6c635b984f5527058c159a38eaa2f23ba6b40cee58321349ca8ff4602273cbccb6b25824ce7d6e5c60c585403551d64e8e3763403d605d79cfc6c5fbe4b4b97ca858b12a0bdb1c16522b74317588521841cf6b1b6424904c8b94d1db8bfdbf63b384abcbb4e2dfadca1188089c0175f7a9d3ca5da2982bee6543e506d8fcd051811bdf22db6b044941ffa462c1c157b0fe698026ff127cc24f1dd8e723d423d505d0b3b997dbdbe48a2b091b779d8ba5963cc47adae92574764712ea8faff0ceb17636f43fc90cfb8316f5b3f1cff0f693aa03abbd9f765d32d21b30d3887e20f637b18e6233f181d0838e6acf7cd2a6bdf

client DH public:

308203243082019706092a864886f70d010301308201880282018100ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf6955817183995497cea956ae515d2261898fa051015728e5a8aaac42dad33170d04507a33a85521abdf1cba64ecfb850458dbef0a8aea71575d060c7db3970f85a6e1e4c7abf5ae8cdb0933d71e8c94e04a25619dcee3d2261ad2ee6bf12ffa06d98a0864d87602733ec86a64521f2b18177b200cbbe117577a615d6c770988c0bad946e208e24fa074e5ab3143db5bfce0fd108e4b82d120a93ad2caffffffffffffffff0201020382018500028201802976565126ca39f3fa767d8b7d8c8d104ebb7e5b14a28223cdd5cc5218b800be87d62e7f43216957a1f2e0b21d82ae7cd285a39ab64fe1099ccf6f15e615d6f692870e5710e47eda748f1ec818d58c73673af1546127d97ad7441612b32695c1928a4b9436ea29e9280bbb80cdeaab3a80f729547898f93d686b8b8e3ba40927d0791784f2f255afa8420047e768ac978d664018aef0ac0abbc00825d9f3761cb4550080b5b4c28b20c438593a04084897f1c782a7136c96f718e4d414ecf25200cc04d27f4b660aa4a53440b252d95dd1879857783d0ee4bd9c71cfdf99851d48f803ca987f5251d6d1fa566870f73c854d2a607ae3ebe0fe0a9b5b09fc55c44311270bf207c9d61d51df0a3c41a5f7d528d4bef1a4653a754850297cf17f8b11b01b501a64aca2c776ee92855d3c4409118a71c4a3963aa0d7cbb1e6d3eeb1bf625dfb87a55d19622c9e57a04d6d05dad9e1f0644339237924a14e07b74e965f0c48fe9e9a5a57f1d2de51cfa330c5d6c104fc20901c4a8ea512e0aaacfb19

Error: Supplied key is too large

at DiffieHellmanGroup.dhComputeSecret [as computeSecret] (internal/crypto/diffiehellman.js:113:29)
at exports.challenge (/usr/src/crypto-oracle/controllers/asymmetric.controller.js:150:34)
at Layer.handle [as handle_request] (/usr/src/crypto-oracle/node_modules/express/lib/router/layer.js:95:5)
at next (/usr/src/crypto-oracle/node_modules/express/lib/router/route.js:137:13)
at Route.dispatch (/usr/src/crypto-oracle/node_modules/express/lib/router/route.js:112:3)
at /usr/src/crypto-oracle/node_modules/express/lib/router/index.js:281:22
at Function.process_params (/usr/src/crypto-oracle/node_modules/express/lib/router/index.js:335:12)
at next (/usr/src/crypto-oracle/node_modules/express/lib/router/index.js:275:10)
at Function.handle (/usr/src/crypto-oracle/node_modules/express/lib/router/index.js:174:3)
GET /asymmetric/dh-challenge/server

令我震惊的是,python 客户端生成的公钥长度始终大于服务器端生成的公钥长度。 我尝试在客户端使用 PEM 编码,但这导致了相同的错误。

遗憾的是,无法将 DH 替换为其他 key 交换方法。

最佳答案

这里的问题很可能是格式不匹配。 Python 代码正在生成 ASN.1 DER 公钥结构,您对其进行十六进制编码。该 DER 结构除了公共(public)值本身之外还包含各种信息,但 Node.js 端的 computeSecret 可能只需要公共(public)值(您应该确认这一点!)。

如果是这种情况,在 Python 端该值为 y可以从 DHPublicNumbers 对象获取。

关于javascript - Python 和 Node 之间的 Diffie-Hellman key 交换失败,并出现错误“提供的 key 太大”,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61430483/

相关文章:

javascript - 是否可以添加一个带有端口的pushEndpoint?

javascript - Greasemonkey:转发整页内容

javascript - 在外部单击时折叠 Bootstrap 按钮

python - pygame 中出现错误 'pygame.surface' 对象不可下标

python - JSON 列作为 kafka 生产者中的键

java - Python 代码比 Java 慢 60 倍

javascript - Class.create 和 this 关键字

javascript - 无法通过 Angular 管道搜索对象数组值

javascript - 如何使用 rollup 加载子目录中的所有文件而不需要 require 语句

node.js - Node js swig对象显示