Android平台椭圆曲线(EC)密钥对签名验证实现求助
Android平台EC密钥对签名与验证实现
没问题,我来帮你完善椭圆曲线(EC)的签名和验证逻辑!结合你已有的密钥对生成代码,下面直接给出可复用的Kotlin实现,也兼容Java写法。
一、签名实现(私钥签名)
我们使用Signature类来实现ECDSA签名,选择SHA256withECDSA算法(SHA-256哈希+EC签名,兼顾安全和性能),和你当前的密钥生成逻辑保持同一Provider("SC")。
import java.security.SecureRandom import java.security.Signature import java.security.PrivateKey fun signString(privateKey: PrivateKey, content: String): ByteArray { // 初始化Signature实例,指定签名算法和Provider val signature = Signature.getInstance("SHA256withECDSA", "SC") // 以签名模式初始化,传入私钥和随机数生成器 signature.initSign(privateKey, SecureRandom()) // 将待签名字符串转为UTF-8字节数组,更新到Signature中 signature.update(content.toByteArray(Charsets.UTF_8)) // 生成签名字节数组 return signature.sign() }
二、验证实现(公钥验证)
验证逻辑和签名完全对应,用公钥初始化Signature为验证模式,对比原内容和签名是否匹配:
import java.security.PublicKey import java.security.Signature fun verifySignature(publicKey: PublicKey, content: String, signatureBytes: ByteArray): Boolean { // 初始化Signature实例,和签名用相同的算法、Provider val signature = Signature.getInstance("SHA256withECDSA", "SC") // 以验证模式初始化,传入公钥 signature.initVerify(publicKey) // 更新原内容的字节数组(编码要和签名时一致) signature.update(content.toByteArray(Charsets.UTF_8)) // 验证签名,返回布尔值表示是否通过 return signature.verify(signatureBytes) }
三、完整使用示例
把密钥生成、签名、验证串起来测试:
import org.bouncycastle.jce.ECNamedCurveTable import org.bouncycastle.jce.spec.ECParameterSpec import java.security.KeyPair import java.security.KeyPairGenerator val parameterSpec = ECNamedCurveTable.getParameterSpec("secp160r1") fun genKeyPair(): KeyPair { val keyPairGenerator = KeyPairGenerator.getInstance("EC", "SC") keyPairGenerator.initialize(parameterSpec, SecureRandom()) return keyPairGenerator.genKeyPair() } fun main() { try { // 1. 生成EC密钥对 val keyPair = genKeyPair() val originalContent = "这是要签名的测试字符串" // 2. 生成签名 val signatureBytes = signString(keyPair.private, originalContent) println("生成的十六进制签名:${signatureBytes.joinToString("") { "%02x".format(it) }}") // 3. 验证签名(正常场景) val isVerified = verifySignature(keyPair.public, originalContent, signatureBytes) println("正常内容验证结果:$isVerified") // 输出true // 4. 篡改内容后验证(测试失败场景) val tamperedContent = originalContent + "【已篡改】" val isTamperedVerified = verifySignature(keyPair.public, tamperedContent, signatureBytes) println("篡改内容验证结果:$isTamperedVerified") // 输出false } catch (e: Exception) { e.printStackTrace() } }
四、注意事项
- 算法一致性:签名和验证必须使用相同的哈希+签名算法(比如都用
SHA256withECDSA),否则验证会失败。如果需要更强的安全性,可以换成SHA512withECDSA。 - 编码统一:字符串转字节数组时要固定编码(这里用UTF-8),避免不同编码导致内容哈希值不一致,进而验证失败。
- 异常处理:实际项目中要捕获
NoSuchAlgorithmException、InvalidKeyException、SignatureException等异常,避免程序崩溃。 - Provider兼容:你当前使用的"SC"是SpongyCastle Provider,如果是Android系统自带的密钥库,Provider名称可能是"AndroidKeyStore",需要根据实际情况调整。
内容的提问来源于stack exchange,提问作者Jabbi
相关产品推荐
相关产品推荐

