Как восстановить открытый 33-байтовый открытый ключ NIST P-256 из 33 байтов? - PullRequest
0 голосов
/ 10 декабря 2018

Предполагается, что открытый ключ, закодированный в 33 байта, может быть создан следующим образом:

Security.addProvider(provider)
val generator = KeyPairGenerator.getInstance("ECDSA")
val ecSpec = ECNamedCurveTable.getParameterSpec("secp256r1")
generator.initialize(ecSpec)
val keyPair = generator.generateKeyPair()
val privateKey = keyPair.private as ECPrivateKey
val publicKey = keyPair.public as ECPublicKey
val publicEncoded = publicKey.q.getEncoded(true)

Как я могу восстановить его на другой стороне (когда у меня только 33 байта, отправленных отсюда)?

Я пробовал ниже код:

val publicKey =KeyFactory.getInstance("EC").generatePublic(X509EncodedKeySpec(publicEncoded))

Но я думаю, что это совершенно неправильно, так как я получаю:

java.security.spec.InvalidKeySpecException: java.lang.RuntimeException: ошибка: 0c000079: подпрограммы кодирования ASN.1: OPENSSL_internal: HEADER_TOO_LONG

Я пытался также:

val generator = KeyPairGenerator.getInstance("ECDSA")
val ecPublicKey = generator
        .generatePublic(X509EncodedKeySpec((publicEncoded))) as ECPublicKey

Но ошибка:

java.security.spec.InvalidKeySpecException: спецификация закодированного ключа не распознана

Как достичь своей цели?

Ответы [ 2 ]

0 голосов
/ 11 декабря 2018

Это должно сделать работу:

import org.bouncycastle.jce.ECNamedCurveTable
import org.bouncycastle.jce.spec.ECPublicKeySpec

fun publicKeyFromCompressed(compressedPublicKey: ByteArray): PublicKey {
    val ecSpec = ECNamedCurveTable.getParameterSpec("secp256r1")
    val point = ecSpec.curve.decodePoint(compressedPublicKey)
    val publicKeySpec = ECPublicKeySpec(point, ecSpec)
    val keyFactory = KeyFactory.getInstance("ECDSA")
    val publicKey = keyFactory.generatePublic(publicKeySpec)
    return publicKey
}
0 голосов
/ 10 декабря 2018

Основная проблема заключается в том, что ваш publicEncoded является не закодированным открытым ключом, а закодированным ECPoint (publicKey.q).Это означает, что вам нужно сначала восстановить точку, а затем предоставить соответствующую кривую, чтобы восстановить ключ для получения правильного ECPublicKeySpec.

  1. Сначала повторно получите выбранную спецификацию кривойс ECNamedCurveTable.getParameterSpec("secp256r1").Затем вы можете использовать ecSpec.curve.decodePoint(publicEncoded) для восстановления экземпляра BC ECPoint.
  2. Превратить BouncyCastle ECNamedCurveParameterSpec в java.security.spec.ECParameterSpec и BouncyCastle ECPoint в java java.security.spec.ECPoint.Затем создайте соответствующий ECPublicKeySpec, который затем может использоваться генератором ключей ECDSA для воссоздания полных PublicKey.

Ссылки:

...