fix: Private key format #2164

This commit is contained in:
J-Jamet
2025-09-14 23:48:27 +02:00
parent 672f1ca37d
commit d5c378ac85
2 changed files with 29 additions and 11 deletions

View File

@@ -19,6 +19,7 @@
*/ */
package com.kunzisoft.keepass.credentialprovider.passkey.data package com.kunzisoft.keepass.credentialprovider.passkey.data
import android.util.Log
import androidx.credentials.exceptions.GetCredentialUnknownException import androidx.credentials.exceptions.GetCredentialUnknownException
import com.kunzisoft.encrypt.Signature import com.kunzisoft.encrypt.Signature
import com.kunzisoft.encrypt.Base64Helper.Companion.b64Encode import com.kunzisoft.encrypt.Base64Helper.Companion.b64Encode
@@ -46,8 +47,12 @@ class AuthenticatorAssertionResponse(
private var signature: ByteArray = byteArrayOf() private var signature: ByteArray = byteArrayOf()
init { init {
signature = Signature.sign(privateKey, dataToSign()) try {
?: throw GetCredentialUnknownException("signing failed") signature = Signature.sign(privateKey, dataToSign())
} catch (e: Exception) {
Log.e(this::class.java.simpleName, "Unable to sign: ${e.message}")
throw GetCredentialUnknownException("Signing failed")
}
} }
private fun dataToSign(): ByteArray { private fun dataToSign(): ByteArray {

View File

@@ -58,12 +58,17 @@ object Signature {
const val ED_DSA_ALGORITHM: Long = -8 const val ED_DSA_ALGORITHM: Long = -8
private const val BEGIN_PRIVATE_KEY = "-----BEGIN PRIVATE KEY-----"
private const val BEGIN_PRIVATE_KEY_LINE_BREAK = "$BEGIN_PRIVATE_KEY\n"
private const val END_PRIVATE_KEY = "-----END PRIVATE KEY-----"
private const val END_PRIVATE_KEY_LINE_BREAK = "\n$END_PRIVATE_KEY"
init { init {
Security.removeProvider(BouncyCastleProvider.PROVIDER_NAME) Security.removeProvider(BouncyCastleProvider.PROVIDER_NAME)
Security.addProvider(BouncyCastleProvider()) Security.addProvider(BouncyCastleProvider())
} }
fun sign(privateKeyPem: String, message: ByteArray): ByteArray? { fun sign(privateKeyPem: String, message: ByteArray): ByteArray {
val privateKey = createPrivateKey(privateKeyPem) val privateKey = createPrivateKey(privateKeyPem)
val algorithmKey = privateKey.algorithm val algorithmKey = privateKey.algorithm
val algorithmSignature = when (algorithmKey) { val algorithmSignature = when (algorithmKey) {
@@ -71,22 +76,30 @@ object Signature {
"ECDSA" -> "SHA256withECDSA" "ECDSA" -> "SHA256withECDSA"
"RSA" -> "SHA256withRSA" "RSA" -> "SHA256withRSA"
"Ed25519" -> "Ed25519" "Ed25519" -> "Ed25519"
else -> null else -> throw SecurityException("$algorithmKey algorithm is unknown")
} }
if (algorithmSignature == null) { val sig = Signature.getInstance(
Log.e(this::class.java.simpleName, "sign: the algorithm $algorithmKey is unknown") algorithmSignature,
return null BouncyCastleProvider.PROVIDER_NAME
} )
val sig = Signature.getInstance(algorithmSignature, BouncyCastleProvider.PROVIDER_NAME)
sig.initSign(privateKey) sig.initSign(privateKey)
sig.update(message) sig.update(message)
return sig.sign() return sig.sign()
} }
fun createPrivateKey(privateKeyPem: String): PrivateKey { fun createPrivateKey(privateKeyPem: String): PrivateKey {
val targetReader = StringReader(privateKeyPem) var privateKeyString = privateKeyPem
if (privateKeyPem.startsWith(BEGIN_PRIVATE_KEY_LINE_BREAK).not()) {
privateKeyString = privateKeyString.removePrefix(BEGIN_PRIVATE_KEY)
privateKeyString = "$BEGIN_PRIVATE_KEY_LINE_BREAK$privateKeyString"
}
if (privateKeyPem.endsWith(END_PRIVATE_KEY_LINE_BREAK).not()) {
privateKeyString = privateKeyString.removeSuffix(END_PRIVATE_KEY)
privateKeyString += END_PRIVATE_KEY_LINE_BREAK
}
val targetReader = StringReader(privateKeyString)
val pemParser = PEMParser(targetReader) val pemParser = PEMParser(targetReader)
val privateKeyInfo = pemParser.readObject() as PrivateKeyInfo val privateKeyInfo = pemParser.readObject() as? PrivateKeyInfo?
val privateKey = JcaPEMKeyConverter().getPrivateKey(privateKeyInfo) val privateKey = JcaPEMKeyConverter().getPrivateKey(privateKeyInfo)
pemParser.close() pemParser.close()
targetReader.close() targetReader.close()