Я пытаюсь выполнить обмен ключами 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 для какого-либо другого метода обмена ключами, к сожалению, не возможна.