如何根据密码在Java中创建密钥对?

我想允许Alice创建公钥/私钥对,以便Bob可以发送她的机密消息.但是,我希望Alice能够从任何地方检查她的消息,并且她必须携带包含她的私钥的记忆棒是一件痛苦的事. Alice是否有某种方法可以根据她记得的密码创建公钥/私钥对?通过这种方式,她可以随时生成私钥(和公钥).

这个问题的简短版本是:我在哪里可以找到相当于cryptico.js的Java.

另外,here’s the same question在Stack Overflow上,但是对于javascript.

编辑:这是我第一次尝试解决方案:

SecureRandom saltRand = new SecureRandom(new byte[] { 1,2,3,4 });
    byte[] salt = new byte[16];
    saltRand.nextBytes(salt);

    int keyLength = 3248;
    SecretKeyFactory factory = SecretKeyFactory
            .getInstance("PBKDF2WithHmacSHA1");
    KeySpec spec = new PBEKeySpec(password.tochararray(),salt,8192,keyLength);
    SecretKey key = factory.generateSecret(spec);

    SecureRandom keyGenRand = SecureRandom.getInstance("SHA1PRNG");
    keyGenRand.setSeed(key.getEncoded());

    KeyPairGenerator gen = KeyPairGenerator.getInstance("RSA");
    gen.initialize(keyLength,keyGenRand);
    java.security.KeyPair p = gen.generateKeyPair();

解决方法

在谈论RSA时:您可以使用PBKDF2的结果来播种伪随机生成器,该生成器又可以用于生成密钥对.请注意,使用SecureRandom将无法正常工作,因为它会将种子添加到池中,而不是完全重新初始化rng. RSA需要PRNG才能找到随机素数.

如果你可以使用Elliptic Curve Cryptography,你会更好.您可以选择F(p)上的标准NIST或Brainpool曲线.然后,您可以使用PBKDF2的32字节输出作为私钥并计算公钥. ECC只需要一个随机私钥,因为PBKDF2的输出应该与随机无法区分,输出就可以了.您不仅需要额外的PRNG,还可以节省自己计算RSA密钥对的时间 – 这可能非常重要.

请注意,没有任何东西可以防止对使用所述计算密钥加密的内容进行暴力攻击,因此您最好要求使用16个字符或更多的密码,包含非字典单词,数字和符号.任何不太可能会失败,特别是如果用户不知道可能的攻击.请注意,如果您没有存储空间,则不能使用随机盐.如果您不能使用随机盐,则无法防御彩虹表(对于您的特定应用,您当然可以使用特定于应用程序的盐).此外,具有相同密码的人将生成相同的私钥.

当然,认方式 – 例如在PGP中 – 是存储使用基于密码的加密加密的私钥.然而,这需要存储.这种方法的优点是你可以拥有一个完全随机的密钥,这意味着如果不访问密钥存储,就无法对密文进行暴力攻击.它增加一个重要的额外层.

相关文章

最近看了一下学习资料,感觉进制转换其实还是挺有意思的,尤...
/*HashSet 基本操作 * --set:元素是无序的,存入和取出顺序不...
/*list 基本操作 * * List a=new List(); * 增 * a.add(inde...
/* * 内部类 * */ 1 class OutClass{ 2 //定义外部类的成员变...
集合的操作Iterator、Collection、Set和HashSet关系Iterator...
接口中常量的修饰关键字:public,static,final(常量)函数...