我正在开发分布式数字签名,签署文档并通过网络将其发送到Application Server.我在
java中使用套接字编程来完成它.我认为应该对公钥进行编码或压缩,即x和y值以某种方式表示为单个二进制数据并保存在公共注册表或网络中.但我不知道如何在java中执行此操作.
// I have class like this public class CryptoSystem{ EllipticCurve ec = new EllipticCurve(new P192()); //------------------- //-------------------- public ECKeyPair generatekeyPair() { return ECKeyPair(ec); } } // i don't think i have problem in the above CryptoSystem crypto = new CryptoSystem(); ECKeyPair keyPair = crypto.generateKeyPair(); BigInteger prvKey = keyPair.getPrivateKey(); ECPoint pubKey = keyPair.getPublicKey(); // recommend me here to compress and send it the public key to a shared network.
我想知道如何对公钥和域参数进行编码,以便签名的验证者将对其进行解码以使用它.因为当您通过网络将它们发送给验证者时,您将必须将其编码为单字节数组我没有使用Bouncy Castle Provider. ECDSA算法的整个实现是我的项目
解决方法
椭圆曲线点几乎总是使用X9.62中指定的编码进行编码.
可以选择使用点压缩.使用点压缩进行编码是微不足道的,但解码压缩点需要更多的工作,所以除非你真的需要保存额外的字节,否则我不会打扰.如果您需要,请告诉我,我会添加详细信息.您可以通过第一个字节(即0x02或0x03)识别带有点压缩的X9.62编码点.
没有点压缩的编码非常简单:从0x04开始(表示没有压缩).然后首先跟随x坐标,然后是y坐标,左边是零填充,直到字段的字节大小:
int qLength = (q.bitLength()+7)/8; byte[] xArr = toUnsignedByteArray(x); byte[] yArr = toUnsignedByteArray(y); byte[] res = new byte[1+2*qLength]; res[0] = 0x04; System.arraycopy(xArr,res,qLength - xArr.length,xArr.length); System.arraycopy(yArr,2* qLength - yArr.length,nLength);
对此进行解码当然是微不足道的.