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

iOS与Java实现RSA签名校验抛出InvalidKeySpecification异常求助

异常原因排查
  • 模数、指数多做了一次Base64编码,导致密钥长度识别错误
    你iOS代码中获取到的publicKey.modulus本身就是128字节的1024位RSA原始模数二进制数据,调用base64EncodedData后得到的是原始模数做Base64编码后的字符对应的二进制数据,长度变为172字节。Java端解码后拿到的不是原始模数,识别到的密钥长度远小于要求的512位,抛出对应异常。
  • 待签名内容两边不一致
    iOS端签名时先把明文转成UTF8字节后额外做了一次Base64编码,对Base64后的字节签名;但Java端校验时直接用明文的UTF8字节做校验,两边待签名内容不匹配,即使密钥正确也会校验失败。
  • 签名哈希算法不匹配
    Heimdall框架默认的签名算法为SHA256withRSA,你Java端使用的是SHA512withRSA,算法不一致会导致校验失败。
修复方案

iOS端代码修改

移除多余的Base64编码逻辑,直接输出原始数据的Base64字符串即可:

self.heimdall = Heimdall(tagPrefix: "com.hnormak.heimdall.example", keySize: 1024)
let text = "Hello World!"
let textData = text.data(using: .utf8)!
let publicKey = heimdall!.publicKeyComponents()!
// 直接将原始模数、指数转为Base64字符串传输
let modulusStr = publicKey.modulus.base64EncodedString()
let exponentStr = publicKey.exponent.base64EncodedString()
// 直接对明文UTF8字节签名,不要额外做Base64编码
let signatureStr = heimdall!.sign(textData)!.base64EncodedString()
let message: NSDictionary = ["text": text, "signature": signatureStr, "modulus": modulusStr, "exponent": exponentStr ]
print(message)

Java端代码修改

对齐签名算法,同时处理无符号字节的识别问题:

public static void main(String[] args) {
    String messageText = "Hello World!";
    // 传入iOS端返回的对应Base64字符串
    final byte[] signature = Base64.decodeBase64("iOS返回的signatureStr");
    final byte[] modulusBytes = Base64.decodeBase64("iOS返回的modulusStr") ;
    final byte[] exponentBytes = Base64.decodeBase64("iOS返回的exponentStr");
    try {
        // 算法和iOS端对齐为SHA256withRSA
        final Signature sig = Signature.getInstance("SHA256withRSA");
        final KeyFactory keyMaker = KeyFactory.getInstance("RSA");
        // 构造BigInteger时指定符号为正,避免iOS返回的无符号字节被识别为负数
        final RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(
                new BigInteger(1, modulusBytes),
                new BigInteger(1, exponentBytes)
        );
        final RSAPublicKey pubKey = (RSAPublicKey)keyMaker.generatePublic( pubKeySpec );
        sig.initVerify( pubKey );
        sig.update( messageText.getBytes() );
        final boolean result = sig.verify( signature );
        System.out.println(result);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

内容的提问来源于stack exchange,提问作者Sathish Thangathurai

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.12 03:18:00