具有JCE的固定长度64字节EC P-256签名 [英] Fixed length 64 Bytes EC P-256 Signature with JCE

查看:149
本文介绍了具有JCE的固定长度64字节EC P-256签名的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要使用NIST P-256曲线的固定长度的64字节ECDSA签名。

I need a fixed length 64 Byte ECDSA signature with the NIST P-256 Curve.

该实现不必使用JCE。

The implementation hast to use JCE.

以下代码示例可以生成签名并进行验证。

The following code sample can generate a signature and verify it.

Provider provSign = new SunEC();
Provider provVerify = new SunEC();


    // generate EC key
    KeyPairGenerator kg = KeyPairGenerator.getInstance("EC", provSign);
    ECGenParameterSpec ecParam = new ECGenParameterSpec("secp256r1");
    kg.initialize(ecParam);      
    KeyPair keyPair = kg.generateKeyPair(); 
    PrivateKey privateKey = keyPair.getPrivate();      
    PublicKey publicKey = keyPair.getPublic();

    try
    {
      // export public key                  
      KeyFactory kf = KeyFactory.getInstance("EC", provSign);
      ECPublicKeySpec publicKeySpec = kf.getKeySpec(keyPair.getPublic(), ECPublicKeySpec.class);

      // import public key into other provider
      kf = KeyFactory.getInstance("EC", provVerify);
      publicKey = (PublicKey)kf.generatePublic(publicKeySpec);      
    }
    catch (InvalidKeySpecException ex)
    {                       
      ex.printStackTrace();
    }


      // do test        
      Signature sig = Signature.getInstance("SHA256withECDSA", provSign);
      Signature ver = Signature.getInstance("SHA256withECDSA", provVerify);

      byte[] data = new byte[64];

      // sign
      sig.initSign(privateKey);
      sig.update(data);
      byte [] sign = sig.sign();

      // Working Signature verification
      ver.initVerify(publicKey);
      ver.update(data);
      if (ver.verify(sign) == false)
      {
        throw new Exception("Signature Verification failed");
      }

问题是符号已经过某种编码(我认为是DER格式)长度在70到72字节之间,但是我需要64字节(未编码/原始)签名。

The problem is that the sign is somehow encoded (I think in DER Format) and is between 70 and 72 Bytes long but I need a 64 Byte (unencoded/raw) signature.

我尝试过的操作:
转换为固定长度64字节签名

What I have tried: Convert to fixed length 64 Byte Signature

      DerInputStream derInputStream = new DerInputStream(sign);
      DerValue[] values = derInputStream.getSequence(2);
      byte[] random = values[0].getPositiveBigInteger().toByteArray();
      byte[] signature = values[1].getPositiveBigInteger().toByteArray();


      // r and s each occupy half the array
      // Remove padding bytes
      byte[] tokenSignature = new byte[64];
      System.arraycopy(random, random.length > 32 ? 1 : 0, tokenSignature, random.length < 32 ? 1 : 0,
              random.length > 32 ? 32 : random.length);
      System.arraycopy(signature, signature.length > 32 ? 1 : 0, tokenSignature, signature.length < 32 ? 33 : 32,
              signature.length > 32 ? 32 : signature.length);

      System.out.println("Full Signature length: "+tokenSignature.length+" r length: "+random.length+" s length"+signature.length);

如何立即检查64字节tokenSignature?
我不知道如何将64字节tokenSignature转换回正确的格式

How to check the 64 Bytes tokenSignature now??? I don't know how to convert the 64 Byte tokenSignature back to the right format

      ver.initVerify(publicKey);
      ver.update(data);
      if (ver.verify(???) == false)
      {
        throw new Exception("Signature Verification failed");
      }

我已经通过BouncyCastle ECDSASigner实现了64字节签名验证。但是我不能使用ECDSASigner,因为它没有扩展SignatureSpi,因此不能与兼容JCE的加密服务器一起使用。

I have achieved the 64 Byte signature verification with BouncyCastle ECDSASigner. But I can't use ECDSASigner because it is not extending SignatureSpi and therefore not working with JCE complient crypto server.

推荐答案

@MaartenBodewes

I got it working now thanks to @MaartenBodewes

//How to Check Signature
byte[] r = Arrays.copyOfRange(tokenSignature, 0,tokenSignature.length/2);
byte[] s = Arrays.copyOfRange(tokenSignature, tokenSignature.length/2,tokenSignature.length);

ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
DEROutputStream derOutputStream = new DEROutputStream(byteArrayOutputStream);
ASN1EncodableVector v=new ASN1EncodableVector();
v.add(new ASN1Integer(new BigInteger(1,r)));
v.add(new ASN1Integer(new BigInteger(1,s)));
derOutputStream.writeObject(new DERSequence(v));
byte[] derSignature = byteArrayOutputStream.toByteArray();

ver.update(data);
if (ver.verify(derSignature) == false)
{
  throw new Exception("Signature Verification failed");
}

这篇关于具有JCE的固定长度64字节EC P-256签名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆