I am trying to verify the GPG signature of a file provided the public key. I am using Kotlin though but the issue is not Kotlin specific, so I didn't know if I should post it here, or in a Kotlin related server. I use the BouncyCaste API. I have verified the signature with GPG but am unable to do it corectly via the BC API. Here is my code:
fun verify(
fileBytes: ByteArray,
signatureInputStream: InputStream,
publicKeyFileInputStream: InputStream,
publicKeyId: Long,
) = getSignature(signatureInputStream).apply {
init(BcPGPContentVerifierBuilderProvider(), getPublicKey(publicKeyFileInputStream, publicKeyId))
update(fileBytes)
}.verify()
private fun getPublicKey(
publicKeyFileInputStream: InputStream,
publicKeyId: Long,
): PGPPublicKey {
val decoderStream = PGPUtil.getDecoderStream(publicKeyFileInputStream)
val pgpPublicKeyRingCollection = PGPPublicKeyRingCollection(decoderStream, BcKeyFingerprintCalculator())
val publicKeyRing = pgpPublicKeyRingCollection.getPublicKeyRing(publicKeyId)
?: throw IllegalArgumentException("Can't find public key ring with ID $publicKeyId.")
return publicKeyRing.getPublicKey(publicKeyId)
?: throw IllegalArgumentException("Can't find public key with ID $publicKeyId.")
}
private fun getSignature(inputStream: InputStream): PGPSignature {
val decoderStream = PGPUtil.getDecoderStream(inputStream)
val pgpSignatureList = PGPObjectFactory(decoderStream, BcKeyFingerprintCalculator()).first {
it is PGPSignatureList
} as PGPSignatureList
return pgpSignatureList.first()
}
fun main() {
verify(
fileBytes = File("file").readBytes(),
signatureInputStream = File("sign").inputStream(),
publicKeyFileInputStream = File("pub").inputStream(),
publicKeyId = 3897925568445097277,
).let {
print(it) // false
}
}