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

如何实现KECCAK-384哈希与NONEwithRSA签名分步操作(无外部库)

解决方案

核心逻辑

由于KECCAK-384无官方标准OID,无法直接通过Signature.getInstance("KECCAK-384withRSA")调用标准签名算法,因此需要手动构造符合PKCS#1规范的DigestInfo DER结构,再通过NoneWithRSA签名该结构,以此等效实现「KECCAK-384哈希→RSA签名」的两步流程。

分步实现

1. 计算KECCAK-384哈希值

Java 11及以上版本原生支持KECCAK哈希算法,直接通过MessageDigest计算:

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

// 待签名原始数据
byte[] rawData = "your data to sign".getBytes();

// 计算KECCAK-384哈希
MessageDigest keccakDigest = MessageDigest.getInstance("KECCAK-384");
byte[] hashValue = keccakDigest.digest(rawData);

2. 手动构造DigestInfo的DER编码

PKCS#1定义的DigestInfo ASN.1结构为:

DigestInfo ::= SEQUENCE {
    digestAlgorithm AlgorithmIdentifier,
    digest OCTET STRING
}

AlgorithmIdentifier ::= SEQUENCE {
    algorithm OBJECT IDENTIFIER,
    parameters ANY DEFINED BY algorithm OPTIONAL
}

KECCAK-384对应的标准OID为2.16.840.1.101.3.4.2.9,我们基于该OID构造DER编码:

import java.io.ByteArrayOutputStream;
import java.io.IOException;

// 1. 构造AlgorithmIdentifier的DER编码
// KECCAK-384 OID的DER编码:06 09 60 86 48 01 65 03 04 02 09
byte[] oidDer = new byte[]{0x06, 0x09, 0x60, (byte)0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x09};
// 参数部分为NULL(KECCAK无额外参数),DER编码:05 00
byte[] paramsDer = new byte[]{0x05, 0x00};

ByteArrayOutputStream algIdBaos = new ByteArrayOutputStream();
algIdBaos.write(0x30); // SEQUENCE标签
algIdBaos.write(oidDer.length + paramsDer.length); // 总长度
algIdBaos.write(oidDer);
algIdBaos.write(paramsDer);
byte[] algIdDer = algIdBaos.toByteArray();

// 2. 构造Digest的OCTET STRING编码
ByteArrayOutputStream digestBaos = new ByteArrayOutputStream();
digestBaos.write(0x04); // OCTET STRING标签
digestBaos.write(hashValue.length); // 哈希值长度
digestBaos.write(hashValue);
byte[] digestDer = digestBaos.toByteArray();

// 3. 构造完整的DigestInfo SEQUENCE
ByteArrayOutputStream digestInfoBaos = new ByteArrayOutputStream();
digestInfoBaos.write(0x30); // SEQUENCE标签
digestInfoBaos.write(algIdDer.length + digestDer.length); // 总长度
digestInfoBaos.write(algIdDer);
digestInfoBaos.write(digestDer);
byte[] digestInfo = digestInfoBaos.toByteArray();

3. 执行RSA签名

与你提供的SHA3-384示例逻辑一致,使用NoneWithRSA签名构造好的DigestInfo:

import java.security.KeyPair;
import java.security.PrivateKey;
import java.security.Signature;
import java.security.NoSuchAlgorithmException;
import java.security.InvalidKeyException;
import java.security.SignatureException;

// 初始化RSA签名实例
Signature signatureEngine = Signature.getInstance("NoneWithRSA");
PrivateKey rsaPrivateKey = yourRsaKeyPair.getPrivate(); // 替换为你的RSA私钥
signatureEngine.initSign(rsaPrivateKey);
signatureEngine.update(digestInfo);
byte[] finalSignature = signatureEngine.sign();

签名验证说明

验证签名时需同步执行以下步骤:

  1. 对原始数据重新计算KECCAK-384哈希
  2. 使用相同OID构造DigestInfo
  3. 初始化NoneWithRSA签名实例,传入公钥后调用verify()方法,传入DigestInfo和签名值

内容的提问来源于stack exchange,提问作者Chico Rico

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 08:50:27