寻找在Java中创建32或16字节密钥的签名算法 [英] Looking for Signing algorithm that creates 32 or 16 byte keys in Java

查看:158
本文介绍了寻找在Java中创建32或16字节密钥的签名算法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

无法匹配使用用于许可申请的公共/私有密钥生成的密钥的大小.我编写了一个自包含的示例,该示例创建公用/专用密钥,通过使用公用密钥对用户的电子邮件地址签名来创建许可证,然后使用公用密钥,许可证和电子邮件地址检查该许可证确实是使用专用密钥编码的(显然,这不会通常都在一堂课里.

Cannot match up the size of key generated using public/private keys for licensing application. Ive written a self contained example that creates public/private key, create a license by signing user emailaddress with public key, and then check using public key, license and email address that the license indeed was encoded using private key (Obviously this wouldn't all be in one class usually).

这一切都可以,但是许可证密钥的十六进制版本是96个字符(即表示48个字节/384位),比我想要的要长一点(相反,公共/私有密钥的长度不是问题,并且越长越好).我可以用什么来生成32个(64个十六进制字符)字节,或者可能生成16个字节(32个十六进制字符),并且这样做的安全性是否合理?

This all works but the hex version of the license key is 96 characters (i.e representing 48 bytes/384 bits) which is a little longer than I wanted (In contrast the length of public/private keys is not a problem and the longer the better). What could I use to generate a 32 (64 hex chars) byte or maybe 16 byte (32 hex chars), and would the security of this be reasonable ?

选择其他算法有点困难,因为我不了解为生成密钥而选择的算法之间的相互作用

Picking another algorithm is somewhat hard as I do not understand the the interaction between the algorithm picked for generating the keys

KeyPairGenerator.getInstance("DSA");

和签名算法

Signature.getInstance("SHA/DSA");

我找不到任何一个列表.

and I cant find a list for either.

当我生成公钥/私钥对时的另一点,我将密钥大小指定为

One other point when I generate a public/private key pairs I specify key size of

keyGen.initialize(1024, new SecureRandom());

公钥(443字节)或私钥(335字节)或二者之和(778字节)都与此数字不匹配.

yet neither the public key (443 bytes) or the private key (335 bytes) or the sum of both (778 bytes) match this number.

import org.apache.commons.codec.binary.Hex;

import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

/**
 *
 */
public class CreateLicense
{

    private String PUBLIC_KEY;
    private String PRIVATE_KEY;

    public static void main(final String[] args)
    {
        try
        {
            String email = args[0];
            System.out.println("Creating license for:"+email);
            CreateLicense cl = new CreateLicense();
            cl.generatePublicPrivateKeyPair();
            String license = cl.createLicense(email);
            cl.checkLicense(email, license);

        }
        catch(Throwable t)
        {
            t.printStackTrace();
        }
    }

    //Would only be done once on server
    private void generatePublicPrivateKeyPair() throws Exception
    {
        final KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA");
        keyGen.initialize(1024, new SecureRandom());
        final KeyPair pair = keyGen.generateKeyPair();
        PrivateKey privateKey = pair.getPrivate();
        PRIVATE_KEY=Hex.encodeHexString(privateKey.getEncoded());
        PublicKey  publicKey = pair.getPublic();
        PUBLIC_KEY=Hex.encodeHexString(publicKey.getEncoded());
        System.out.println("PrivateKeyHexLength:"+privateKey.getEncoded().length);
        System.out.println("PublicKeyHexLength:"+publicKey.getEncoded().length);

    }

    private PrivateKey reinflatePrivateKey(String keyAsHexString) throws Exception
    {
        byte[] keyBytes = Hex.decodeHex(keyAsHexString.toCharArray());
        final  PKCS8EncodedKeySpec privKeySpec = new PKCS8EncodedKeySpec(keyBytes);
        final  KeyFactory keyFactory = KeyFactory.getInstance("DSA");
        final  PrivateKey privateKey = keyFactory.generatePrivate(privKeySpec);
        return privateKey;
    }

    private PublicKey reinflatePublicKey(String keyAsHexString) throws Exception
    {
        byte[] keyBytes = Hex.decodeHex(keyAsHexString.toCharArray());
        final  X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(keyBytes);
        final  KeyFactory keyFactory = KeyFactory.getInstance("DSA");
        final  PublicKey publicKey = keyFactory.generatePublic(pubKeySpec);
        return publicKey;
    }

    //License Create on server based on email address
    private String createLicense(String emailAddress) throws Exception
    {
        String message=emailAddress;
        PrivateKey privateKey =  reinflatePrivateKey(PRIVATE_KEY);
        final Signature dsa = Signature.getInstance("SHA/DSA");
        dsa.initSign(privateKey);
        dsa.update(message.getBytes());
        final byte[] m1 = dsa.sign();
        String license =  Hex.encodeHexString(m1);
        System.out.println("CreateLicense:"+license+":Size:"+license.length());
        return license;
    }

    //Client checks that given known emailaddress and public key that a if a license was derived from
    //that and corresponding privatekey it would match license.
    private boolean checkLicense(String  emailAddress, String license) throws Exception
    {
        String message=emailAddress;
        PublicKey publicKey =  reinflatePublicKey(PUBLIC_KEY);
        final Signature dsa = Signature.getInstance("SHA/DSA");
        dsa.initVerify(publicKey);
        dsa.update(message.getBytes());

        boolean result = dsa.verify(Hex.decodeHex(license.toCharArray()));
        System.out.println("Result"+result);
        return result;
    }
}

给出类似的输出

Creating license for:testuser@nowhere.com
PrivateKeyHexLength:335
PublicKeyHexLength:443
CreateLicense:302c021425f7ad7289b073f82a1d808838f43e0134c5591402140d2a7a4e3967706d4659dc73ace6455040a5fc6b:Size:92
Resulttrue

推荐答案

@Paul-我认为您的解决方案是使用ECDSA. 更改代码行

@Paul - I think your solution here would be to use ECDSA. Change your line of code

final KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA");

final KeyPairGenerator keyGen = KeyPairGenerator.getInstance("ECDSA");

密钥比DSA短得多-我敢肯定,十六进制版本签名会更短.我建议您使用256或128位的主要ECC曲线.

The keys are much shorter than DSA - and I'm sure hex version signature would be shorter. I suggest you use a prime ECC curve of say 256 or 128 bits.

请告诉我们是否可以解决问题.

Please let us know if this solves the problem.

这篇关于寻找在Java中创建32或16字节密钥的签名算法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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