problem: cannot verify signature in browser
solution: support NIST P-256 curve which is supported by browser's webcrypto
This commit is contained in:
committed by
GitHub
parent
aeea27bb70
commit
de5720897a
@@ -5,13 +5,25 @@ import java.util.Locale
|
||||
class SignatureConfig {
|
||||
|
||||
enum class Algorithm {
|
||||
SECP256K1
|
||||
SECP256K1,
|
||||
NIST_P256;
|
||||
|
||||
fun getCurveName(): String {
|
||||
return if (this == SECP256K1) {
|
||||
"secp256k1"
|
||||
} else if (this == NIST_P256) {
|
||||
"secp256r1"
|
||||
} else {
|
||||
throw IllegalStateException()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun algorithmOfString(algo: String): Algorithm {
|
||||
val algorithm = when (algo.uppercase(Locale.getDefault())) {
|
||||
"SECP256K1" -> Algorithm.SECP256K1
|
||||
"NIST_P256", "NIST-P256", "NISTP256", "SECP256R1" -> Algorithm.NIST_P256
|
||||
else -> throw IllegalArgumentException("Unknown algorithm or not allowed")
|
||||
}
|
||||
return algorithm
|
||||
|
||||
@@ -6,7 +6,7 @@ import java.security.MessageDigest
|
||||
import java.security.Signature
|
||||
import java.security.interfaces.ECPrivateKey
|
||||
|
||||
class Secp256KSigner(
|
||||
class EcdsaSigner(
|
||||
private val privateKey: ECPrivateKey,
|
||||
val keyId: Long,
|
||||
) : ResponseSigner {
|
||||
@@ -37,28 +37,32 @@ open class ResponseSignerFactory(
|
||||
private fun readKey(algorithm: SignatureConfig.Algorithm, pem: PemObject): Pair<ECPrivateKey, Long> {
|
||||
val keyFactory = KeyFactory.getInstance("EC")
|
||||
val key = when (algorithm) {
|
||||
SignatureConfig.Algorithm.SECP256K1 -> {
|
||||
SignatureConfig.Algorithm.SECP256K1, SignatureConfig.Algorithm.NIST_P256 -> {
|
||||
val keySpec = PKCS8EncodedKeySpec(pem.content)
|
||||
keyFactory.generatePrivate(keySpec)
|
||||
}
|
||||
}
|
||||
|
||||
if (key !is ECPrivateKey) {
|
||||
throw IllegalStateException("Only ECDSA SECP256K1 keys are allowed")
|
||||
throw IllegalStateException("Only EC keys are allowed")
|
||||
}
|
||||
|
||||
if (key.params.toString() != "secp256k1 (1.3.132.0.10)") {
|
||||
throw IllegalStateException("Only SECP256K1 are allowed for signing a response")
|
||||
if (algorithm == SignatureConfig.Algorithm.SECP256K1 && key.params.toString().indexOf(SignatureConfig.Algorithm.SECP256K1.getCurveName()) < 0) {
|
||||
throw IllegalStateException("Key is not SECP256K1, generate SECP256K1 or use another algorithm")
|
||||
}
|
||||
|
||||
val publicKey = extractPublicKey(keyFactory, key)
|
||||
if (algorithm == SignatureConfig.Algorithm.NIST_P256 && key.params.toString().indexOf(SignatureConfig.Algorithm.NIST_P256.getCurveName()) < 0) {
|
||||
throw IllegalStateException("Key is not NIST P256, generate NIST P256 or use another algorithm")
|
||||
}
|
||||
|
||||
val publicKey = extractPublicKey(keyFactory, key, algorithm)
|
||||
val id = getPublicKeyId(publicKey)
|
||||
|
||||
return Pair(key, id)
|
||||
}
|
||||
|
||||
fun extractPublicKey(keyFactory: KeyFactory, privateKey: ECPrivateKey): PublicKey {
|
||||
val ecSpec = ECNamedCurveTable.getParameterSpec("secp256k1")
|
||||
fun extractPublicKey(keyFactory: KeyFactory, privateKey: ECPrivateKey, algorithm: SignatureConfig.Algorithm): PublicKey {
|
||||
val ecSpec = ECNamedCurveTable.getParameterSpec(algorithm.getCurveName())
|
||||
val q: ECPoint = ecSpec.g.multiply(privateKey.s)
|
||||
return keyFactory.generatePublic(ECPublicKeySpec(q, ecSpec))
|
||||
}
|
||||
@@ -79,7 +83,7 @@ open class ResponseSignerFactory(
|
||||
return NoSigner()
|
||||
}
|
||||
val key = readKey(config.algorithm, config.privateKey!!)
|
||||
return Secp256KSigner(key.first, key.second)
|
||||
return EcdsaSigner(key.first, key.second)
|
||||
}
|
||||
|
||||
override fun getObjectType(): Class<*>? {
|
||||
|
||||
Reference in New Issue
Block a user