无法匹配使用用于许可应用程序的公钥/私钥生成的密钥大小。我编写了一个自包含的示例,该示例创建公钥/私钥,通过使用公钥签署用户电子邮件地址来创建许可证,然后使用公钥、许可证和电子邮件地址检查许可证确实是使用私钥编码的(显然这不会通常都在一个班级)。
这一切都有效,但是许可证密钥的十六进制版本是 96 个字符(即代表 48 字节/384 位),这比我想要的长一点(相比之下,公钥/私钥的长度不是问题,越长越好)。我可以用什么来生成 32(64 个十六进制字符)字节或 16 个字节(32 个十六进制字符),这样的安全性是否合理?
选择另一种算法有点困难,因为我不了解为生成密钥而选择的算法之间的交互
KeyPairGenerator.getInstance("DSA");
和签名算法
Signature.getInstance("SHA/DSA");
我找不到任何一个列表。
另一点当我生成公钥/私钥对时,我指定密钥大小
keyGen.initialize(1024, new SecureRandom());
然而,公钥(443 字节)或私钥(335 字节)或两者之和(778 字节)都不匹配这个数字。
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