You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 03:32:09