用RSA公钥和私钥加密和解密一个SecretKey
我想用我的publicKey加密一个secretKey,然后用私钥将其解密到别的地方。我可以很好地加密和解密,但是当我这样做时,我得到了一个完全不同的密钥。用RSA公钥和私钥加密和解密一个SecretKey
这里是
public static KeyPair generateKeyPair()
{
KeyPair returnPair = null;
try
{
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", "SunJSSE");
System.out.println("provider:" + kpg.getProvider().getName());
SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
kpg.initialize(1024, random);
returnPair = kpg.generateKeyPair();
}catch(Exception e)
{
e.printStackTrace();
}
return returnPair;
}
我指定的SunJSSE提供商创建的公共代码/私有密钥对,虽然我没有得到任何不同的结果,当我DiffieHellman跑离了SunJCE或RSA/SunRSASign提供商。我是java安全新手,所以这些概念仍然比我头脑还高。
这里是我用来生成密钥
public static SecretKey generateSecretKey(String keyPassword)
{
SecretKey key = null;
try
{
SecretKeyFactory method = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
//System.out.println("salt length: " + new SaltIVManager().getSalt().length);
PBEKeySpec spec = new PBEKeySpec(keyPassword.toCharArray(), new SaltIVManager().getSalt(), 10000, 128);
key = method.generateSecret(spec);
System.out.println("generate secret key length: " + key.getEncoded().length);
}catch(Exception e)
{
e.printStackTrace();
}
return key;
}
而且这里有两种方法我用加密代码/解密我的秘密密钥
public static byte[] encryptSecretKey(SecretKey secretKey, PublicKey publicKey)
{
byte[] encryptedSecret = null;
try
{
Cipher cipher = Cipher.getInstance("RSA/ECB/NOPADDING");
System.out.println("provider: " + cipher.getProvider().getName());
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
System.out.println("original secret key: " + Base64.getEncoder().encodeToString(secretKey.getEncoded()) + " \n secretkey encoded length: " + secretKey.getEncoded().length);
encryptedSecret = cipher.doFinal(secretKey.getEncoded());
System.out.println("encrypted secret: " + Base64.getEncoder().encodeToString(encryptedSecret));
}catch(Exception e)
{
e.printStackTrace();
}
return encryptedSecret;
}
public static SecretKey decryptSecretKey(byte[] encryptedKey, PrivateKey privateKey)
{
SecretKey returnKey = null;
try
{
Cipher cipher = Cipher.getInstance("RSA/ECB/NOPADDING");
System.out.println("provider: " + cipher.getProvider().getName());
cipher.init(Cipher.DECRYPT_MODE, privateKey);
System.out.println("encryptedkey length: " + encryptedKey.length);
byte [] encodedSecret = cipher.doFinal(encryptedKey);
System.out.println("encoded Secret after decrypt: " + Base64.getEncoder().encodeToString(encodedSecret));
returnKey = new SecretKeySpec(encodedSecret, 0, encodedSecret.length, "PBEWithMD5AndDES");
System.out.println("secret key: " + Base64.getEncoder().encodeToString(returnKey.getEncoded()));
System.out.println("secret key length post decrypt: " + returnKey.getEncoded().length);
}catch(Exception e)
{
e.printStackTrace();
}
return returnKey;
}
RSA算法是唯一我已经开始使用我的钥匙了。如果我指定了DiffieHellman alg。对于密钥对,我无法加密/解密。如果有人对我做错了什么有所了解,任何帮助将不胜感激。当我把这种在其当前状态,我与此值= cGFzczEyMw的秘密密钥开始==并用该值的加密/解密
SvMNufKu2JA4hnNEwuWdOgJu6FxnNmuLYzxENhTsGgFzc/i3kQIXbeVaJUkJck918BLCnm2u2QZCyVvJjYFXMLBFga0Zq0WMxSbIZvPz1J/EDi9dpsAkbFhLyBWmdDyPr + w7DMDsqHwKuA8y/IRKVINWXVrp3Hbt8goFZ0nGIlKVzMdJbGhNi3HZSAw4R6fXZNKOJ3nN6wDldzYerEaz2MhJqnZ3Dz4psA6gskomhjp/G0yhsGO8pllMcgD0jzhL86RGrBhjj04Bj0ps3AAACkQLcCwisso8dWigvR8NX9dnI0C后一个结束键/ gc6FqmNenWI1/AoPgmcRyFdlO7A2i9JXoSj + YQ ==
你首先应该知道你正在尝试做之前做:
- 没有填充的RSA是完全不安全的;
- 您使用密码基密码进行密码验证,只有密码才有意义;
- 你拿出一个DES密钥,它又是完全不安全的;
- 你可能用一个随机的盐生成它,所以输出是随机的。
整个协议没有意义。你试图直接用DH(一种执行密钥协议的方案)进行加密表明你还没有研究足够的密码。
加密技术并不是要让事情发挥作用。这是关于让事情安全。你不能仅仅尝试一下就做到这一点。至少学习密码学的基础知识,然后编码。
问题实际上是我存储/检索我的密钥的方式。我曾经使用私人密钥存储和公共文件。我检索这些密钥的方式导致它们变得格格不入,因此我的密码失败,需要使用NOPADDING运行以获得任何输出。 以下是我用于RSA密钥的新存储代码 - 将它们写入文件。
public static boolean saveKeys(Key privateKey, Key publicKey, char[] password, String alias)
{
boolean saved = false;
try
{
KeyPair kp = generateKeyPair();
KeyFactory kf = KeyFactory.getInstance("RSA");
if(privateKey != null)
{
File privKeyFile = new File(System.getProperty("user.home") + "/.etc/privkey");
if(!privKeyFile.exists())
{
privKeyFile.createNewFile();
}
System.out.println("private key: " + Base64.getEncoder().encodeToString(kp.getPrivate().getEncoded()));
RSAPrivateKeySpec pubSpec = kf.getKeySpec(kp.getPrivate(), RSAPrivateKeySpec.class);
ObjectOutputStream oout = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(System.getProperty("user.home") + "/.etc/privkey")));
oout.writeObject(pubSpec.getModulus());
oout.writeObject(pubSpec.getPrivateExponent());
oout.close();
}if(publicKey != null)
{
File pubKeyFile = new File(System.getProperty("user.home") + "/.etc/pubkey.pub");
if(!pubKeyFile.exists())
{
pubKeyFile.createNewFile();
}
System.out.println("public key: " + Base64.getEncoder().encodeToString(kp.getPublic().getEncoded()));
RSAPublicKeySpec pubSpec = kf.getKeySpec(kp.getPublic(), RSAPublicKeySpec.class);
ObjectOutputStream oout = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(System.getProperty("user.home") + "/.etc/pubkey.pub")));
oout.writeObject(pubSpec.getModulus());
oout.writeObject(pubSpec.getPublicExponent());
oout.close();
}
}catch(Exception e)
{
e.printStackTrace();
}
return saved;
}
我使用了PBE的密码,而不是上面建议的密钥。我从来没有拿出DES密钥,所以我不确定你在哪里看到这个。另外,我没有按照你的建议对DH进行加密/解密,尽管我试图从这个算法中得到一个工作密钥。该代码完全显示了我正在尝试的内容。我相信这些都是基本概念。 – SteveManC
您正在使用“PBEWithMD5AndDES”... –
我的错误。谢谢 – SteveManC