Diff ie - Обмен ключами Хеллмана между Python и узлом завершается неудачно с ошибкой. Поставляемый ключ слишком большой - PullRequest
1 голос
/ 25 апреля 2020

Я пытаюсь выполнить обмен ключами DH между клиентом Python 3.6 и сервером Node, работающим в контейнере Docker, с последним образом узла (версия узла: v13.10.1).

Я использую библиотеку cryptography.io (2.9.2) на стороне клиента python. Клиент генерирует ключи DH и отправляет шестнадцатеричный ключ publi c на сервер. Вот фрагмент кода:

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. Вот фрагмент кода:

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);
    ...
}

Я зарегистрировал оба ключа publi c просто для сравнения структуры, я не ожидаю, что они будут одинаковыми. Вывод выглядит примерно так:

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

Меня поражает то, что длина ключа publi c, сгенерированного клиентом python, постоянно больше, чем тот, который сгенерирован на на стороне сервера. Я попытался использовать кодирование PEM на стороне клиента, но это привело к той же ошибке.

Замена DH для какого-либо другого метода обмена ключами, к сожалению, не возможна.

1 Ответ

3 голосов
/ 26 апреля 2020

Весьма вероятно, что проблема заключается в несоответствии форматов. Код Python создает структуру ключа ASN.1 DER publi c, которую вы используете в шестнадцатеричном коде. Эта структура DER содержит различную информацию в дополнение к самому значению publi c, но вполне вероятно, что computeSecret на стороне node.js хочет просто значение publi c (вы должны это подтвердить!).

Если это так, то со стороны Python это значение равно y и может быть получено из объекта DHPublicNumbers.

...