当前位置: 首页 > 知识库问答 >
问题:

带JCE的固定长度64字节EC P-256签名

杨乐意
2023-03-14

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

实现必须使用JCE。

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");
      }
      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);
      ver.initVerify(publicKey);
      ver.update(data);
      if (ver.verify(???) == false)
      {
        throw new Exception("Signature Verification failed");
      }

共有1个答案

吴欣悦
2023-03-14

多亏了@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");
}
 类似资料:
  • 我需要生成一个固定长度的文本行: 我现在有的是: 这非常有用,因为生成了一个55个字符的固定长度的字符串。 例如,当可选值为空字符串时,就会出现问题,例如: 在string.format中有空字符串不会给出固定的长度,我仍然需要有30个字符的长度。 任何线索都非常感谢!! 谢谢

  • 我想生成一个固定长度的散列字符串。我正在为此使用MessageDigest API。我注意到API中的这个函数,但它返回的是整数而不是字节数组。 当我尝试使用此重载摘要方法时,我得到 java.security.DigestException:对于 SHA-256 摘要,长度必须至少为 32,或者输出缓冲区对于指定的偏移量和长度来说太小。 有人能举个例子来说明如何生成固定长度的哈希值吗?

  • 我需要允许网站的老用户使用相同的凭证访问新网站。数据库服务器版本是Microsoft SQL Server 2005,我没有权限更改数据库。数据库的密码列设置为varchar(50),摘要为48个字符。我所知道的关于密码的唯一信息是,它们已经用sha-256算法进行了哈希处理,但据我所知,阿沙-256摘要是64个字符,而不是48个。有可能用sha256生成同样的48长度摘要吗?

  • 问题内容: 我有一个字节数组,固定长度为4。 我需要将每个字节设置为随机字节。如何以最有效的方式这样做?就我而言,这些方法没有提供随机字节功能。 也许有一种内置的方式,还是我应该生成一个随机字符串并将其转换为字节数组? 问题答案: 包兰特 func Read 读取从默认源生成len(p)个随机字节,并将它们写入p。它总是返回len(p)和nil错误。 f unc(* Rand)读 读取生成len(

  • 问题内容: 假设我得到一个介于1到127之间的随机数。我将该数字更改为二进制,并使用下面的代码将其从中删除: 现在,我想通过在必要时以零填充开头来使其长度为7个字符。我认为我需要使用一个for循环,但是有人可以告诉我该怎么做吗? 问题答案: 不,你不会。

  • 我需要产生固定长度的字符串来生成一个基于字符位置的文件。缺少的字符必须用空格字符填充。 例如,字段CITY具有15个字符的固定长度。对于输入“芝加哥”和“里约热内卢”,输出为