End2End шифрование с помощью алгоритма webcrypto api ECDH

Я генерирую открытый и закрытый ключи, используя криптографический API собственного браузера, как показано ниже:

      export const generateKeyPair = async (): Promise<CryptoKeyPair> => {
    return await window.crypto.subtle.generateKey(
        {
            name: "ECDH",
            namedCurve: "P-384",
        },
        true,
        ["deriveKey", "deriveBits"],
    );
};

Затем я экспортирую publicKey используя exportKey функционировать под window.crypto.subtle как показано ниже:

      const keyPair: CryptoKeyPair = yield generateKeyPair();
const publicKeyArrayBuffer: ArrayBuffer = yield window.crypto.subtle.exportKey("raw", keyPair.publicKey);
const publicKeyAsBase64 = arrayBufferToBase64(publicKeyArrayBuffer);

Но мы сталкиваемся с этой ошибкой на стороне Backend (которая написана на Java):

      'java.security.InvalidKeyException: IOException: algid parse error, not a sequence' and exception = 'java.security.InvalidKeyException: IOException: algid parse error, not a sequence' java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: IOException: algid parse error, not a sequence|\tat sun.security.ec.ECKeyFactory.engineGeneratePublic(ECKeyFactory.java:157) ~[jdk.crypto.ec:?]|\tat java.security.KeyFactory.generatePublic(KeyFactory.java:352)

Если у вас есть предложения, дайте мне знать и помогите решить эту проблему.

1 ответ

Решение

Оба кода используют разные кривые, код Java secp256r1 (он же P-256), код JavaScript P-384. Чтобы оба кода были совместимы, код JavaScript должен применять ту же кривую, что и код Java, то есть P-256 (см. Также здесь ).

Код Java экспортирует открытый ключ EC в формате X.509 / SPKI, который закодирован в Base64. Код JavaScript экспортирует открытый ключ в несжатом формате. 0x04|<x>|<y>. Экспорт в формате X.509 / SPKI возможен с spkiкак 1-й параметр, s. здесь и здесь .

Другие вопросы по тегам