Java - 使用现有公钥文件加密字符串

use*_*564 11 java encryption rsa

我在过去的4-5个小时里一直在研究这个问题,尽管找到了"答案",使用了从几种方法到整个~100系列的所有内容,但似乎无法找到真正有效的答案.我无法想象没有一些简单的功能来做这么微不足道的事情:P

我有一套预先存在的公钥/私钥(实际上是两套 - 一个是由ssh-keygen生成的,另一个是由openssl生成的......所以无论什么格式都很酷).

我所追求的只是一个简单的java,相当于我在python中写的东西 -

key_object = someModule.KeyObject(nameOfPublicKeyFile)

def encrypt (SomePlainText) :
  return someOtherModule.encrypt(key_object, SomePlainText)
Run Code Online (Sandbox Code Playgroud)

任何帮助都是极好的!

Jim*_*ood 50

shell中的这些openssl命令创建一个RSA密钥对,并将公钥和私钥写入DER格式的文件.

这里,私钥文件没有密码保护(-nocrypt)以保持简单.

$ openssl genrsa -out keypair.pem 2048
Generating RSA private key, 2048 bit long modulus
............+++
................................+++
e is 65537 (0x10001)
$ openssl rsa -in keypair.pem -outform DER -pubout -out public.der
writing RSA key
$ openssl pkcs8 -topk8 -nocrypt -in keypair.pem -outform DER -out private.der
Run Code Online (Sandbox Code Playgroud)

现在您已拥有DER文件,您可以使用Java读取它们并使用KeySpecKeyFactory来创建PublicKeyPrivateKey对象.

public byte[] readFileBytes(String filename) throws IOException
{
    Path path = Paths.get(filename);
    return Files.readAllBytes(path);        
}

public PublicKey readPublicKey(String filename) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException
{
    X509EncodedKeySpec publicSpec = new X509EncodedKeySpec(readFileBytes(filename));
    KeyFactory keyFactory = KeyFactory.getInstance("RSA");
    return keyFactory.generatePublic(publicSpec);       
}

public PrivateKey readPrivateKey(String filename) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException
{
    PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(readFileBytes(filename));
    KeyFactory keyFactory = KeyFactory.getInstance("RSA");
    return keyFactory.generatePrivate(keySpec);     
}
Run Code Online (Sandbox Code Playgroud)

使用公钥和私钥,您可以加密和解密少量数据(符合您的RSA模数.)我建议使用OAEP填充.

public byte[] encrypt(PublicKey key, byte[] plaintext) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException
{
    Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA1AndMGF1Padding");   
    cipher.init(Cipher.ENCRYPT_MODE, key);  
    return cipher.doFinal(plaintext);
}

public byte[] decrypt(PrivateKey key, byte[] ciphertext) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException
{
    Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA1AndMGF1Padding");   
    cipher.init(Cipher.DECRYPT_MODE, key);  
    return cipher.doFinal(ciphertext);
}
Run Code Online (Sandbox Code Playgroud)

在这里,它通过简单的加密和解密绑定在一起:

public void Hello()
{
    try
    {
        PublicKey publicKey = readPublicKey("public.der");
        PrivateKey privateKey = readPrivateKey("private.der");
        byte[] message = "Hello World".getBytes("UTF8");
        byte[] secret = encrypt(publicKey, message);
        byte[] recovered_message = decrypt(privateKey, secret);
        System.out.println(new String(recovered_message, "UTF8"));
    }
    catch (Exception e)
    {
        e.printStackTrace();
    }
}
Run Code Online (Sandbox Code Playgroud)