I generate an ECDSA PKI and a signature. I need to verify the signature in Python. But the verifier I make in Python can't verify the signature from android.
This is the code I use to generate the PKI and signature. I use secp256r1 curve and "SHA256withECDSA" option.
// Generate key store
keyStore = KeyStore.getInstance("AndroidKeyStore").apply {
load(null)
}
// Set Key spec for Alice
val paramSpec = KeyGenParameterSpec.Builder(
aliasAlice,
KeyProperties.PURPOSE_SIGN or KeyProperties.PURPOSE_VERIFY
).run {
setAlgorithmParameterSpec(ECGenParameterSpec("secp256r1"))
setDigests(
KeyProperties.DIGEST_SHA512,
KeyProperties.DIGEST_SHA256
)
setUserAuthenticationRequired(false)
build()
}
val kpg: KeyPairGenerator = KeyPairGenerator.getInstance(
KeyProperties.KEY_ALGORITHM_EC,
"AndroidKeyStore"
)
kpg.initialize(paramSpec)
val privateKey = keyStore.getKey(aliasAlice, null) as PrivateKey
val publicKey = keyStore.getCertificate(aliasAlice).publicKey
val signature : ByteArray = Signature.getInstance("SHA256withECDSA").run {
initSign(privateKey)
update("random text".toByteArray())
sign()
}
I export public key in PER format and import it to python Public Key example
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEH4OjpeXBF0pEQ6gytvxV+7qbyEQo
b7TgeMWjX7xs
hTkaXh6PKAFYmnjE3qeY3xgMfZQunRpuba5IeZyKp3PhZg==
-----END PUBLIC KEY-----
Signature example(Hex string)
"3045022100868161225C1620215BFB65B7CB797CB3D6E0B9DA0FB355FDD2A1595ECC2D229202205AD3C651826DBD0834F76E6F596363C576B489F45FFA2E77A06F3C1B6BF541AC"
Before verify in python I try to decode asn1 DER of the signature. Because pycryptodom want 64byte length signature but my signature length is 70-72byte. So I manually make a decoder for it.
[Rule]
- 6 byte | DER encoding overhead
- 32 byte | r-value
- (1 byte) | r-value padding (if needed)
- 32 byte | S-value
- (1 byte) | S-value padding (if needed)
- 1 byte | Signature Hash
# Decoder for signature
def der_decoder(signature):
len_r = int(signature[6:8], 16)
if len_r == 32:
hex_r = signature[8:72]
else:
hex_r = signature[10:74]
hex_s = signature[-64:]
return hex_r+hex_s
Verify code in Python
from Crypto.Hash import SHA256
from Crypto.PublicKey import ECC
from Crypto.Signature import DSS
# import public key & generate verifier
public_key = ECC.import_key(publicKey)
verifier = DSS.new(public_key, 'fips-186-3')
# signed message
message = bytes("random text", 'ascii')
hashed_message = SHA256.new(message)
decoded_signature = der_decoder.der_decoder(hex_string_signature)
ba_signature = hex2ba(decoded_signature)
signature = bytes.fromhex(decoded_signature)
print(verifier.verify(hashed_message, signature))
The python code doesn't make any error, but the verifier said the signature is not valid.(It print out False). I don't know how to fix it.... I would appreciate it if you could give me any advice.