我使用secp256k1来签署服务器中文本的哈希并验证客户端的签名。 现在,我需要将实际文本发送给客户端,但我的主要约束是带宽,我无法单独添加文本。因此,我需要能够将实际文本放入签名中并在验证期间将其解压缩?
这是我的代码
签名
static final X9ECParameters curve = SECNamedCurves.getByName ("secp256k1");
static final ECDomainParameters domain = new ECDomainParameters(curve.getCurve (), curve.getG (), curve.getN (), curve.getH ());
public byte[] sign (byte[] hash) throws CryptoException
{
if ( priv == null )
{
throw new CryptoException (ErrorCode.KEY_NOT_FOUND, "Need private key to sign");
}
ECDSASigner signer = new ECDSASigner(new HMacDSAKCalculator(new SHA256Digest()));
signer.init (true, new ECPrivateKeyParameters(priv, domain));
BigInteger[] signature = signer.generateSignature (hash);
ByteArrayOutputStream s = new ByteArrayOutputStream();
try
{
DERSequenceGenerator seq = new DERSequenceGenerator(s);
seq.addObject (new ASN1Integer(signature[0]));
seq.addObject (new ASN1Integer(signature[1]));
seq.close ();
return s.toByteArray ();
}
catch ( IOException e )
{
}
return null;
}
验证
public static boolean verify (byte[] hash, byte[] signature, byte[] pub)
{
ASN1InputStream asn1 = new ASN1InputStream(signature);
try
{
ECDSASigner signer = new ECDSASigner();
signer.init (false, new ECPublicKeyParameters(curve.getCurve ().decodePoint (pub), domain));
DLSequence seq = (DLSequence) asn1.readObject ();
BigInteger r = ((ASN1Integer) seq.getObjectAt (0)).getPositiveValue ();
BigInteger s = ((ASN1Integer) seq.getObjectAt (1)).getPositiveValue ();
return signer.verifySignature (hash, r, s);
}
catch ( Exception e )
{
// threat format errors as invalid signatures
return false;
}
finally
{
try
{
asn1.close ();
}
catch ( IOException e )
{
}
}
}
答案 0 :(得分:2)
ECDSA要求对邮件的哈希是安全的。所以所有信息都丢失了。一些签名方案使用消息的散列+部分。例如,ISO / IEC 9796签名方案中的RSA给出(部分)消息恢复 - 这是您(和Dave Thompson)所谈论的技术术语。
然而,ECDSA签名足以包含单个哈希(通常甚至不包含);没有太多可以做的事情来将数据添加到哈希值。尝试使用EC签名进行部分邮件恢复是徒劳的(也是因为如何执行验证)。
但是如果你想使用更少的比特,你仍然可以做的事情:
我把BLS方案放在最后因为它通常不在通用库中;我认为这是专家的出路。你可能会达到学习曲线。
顺便提一下,签名本身并不能很好地压缩,除非你对它们进行严格的编码。压缩的另一个缺点是,计算所有可能消息的最大大小通常很棘手。
答案 1 :(得分:1)
数字签名ECDSA或RSA通常不包含该消息(请参阅@ dave_thompson_085注释)。 “附加签名”是指基本上包含消息和数字签名的文件,可以用CMS或XMLDsig格式进行编码。
因此,如果您需要发送消息和签名,只需使用自定义或已知格式将它们一起发送,然后另外压缩它以减小大小
AttachedSignature = zip(format(message + signature))