Java - 使用现有公钥文件加密字符串 [英] Java - Encrypt String with existing public key file

查看:243
本文介绍了Java - 使用现有公钥文件加密字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在研究这个过去4-5个小时,似乎找不到一个实际工作的答案,尽管发现'答案',使用从几种方法到整个〜100线班。我不能想象没有一些简单的功能来做这样一个微不足道的事情:P



我有一个预先存在的一组公钥/私钥,两组 - 一个由ssh-keygen生成,另一个由openssl生成,任何格式的工作都很酷)。



所有我之后是一个简单的java,相当于我在python中写的,如 -

 $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ 


解决方案

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



这里,私钥文件不受密码保护(-nocrypt),以保持简单。

  $ openssl genrsa -out keypair.pem 2048 
生成RSA私钥,2048位长模块
............ +++
........ ........................ +++
e是65537(0x10001)
$ openssl rsa -in keypair.pem -outform DER -pubout -out public.der
写入RSA密钥
$ openssl pkcs8 -topk8 -nocrypt -in keypair.p em -outform DER -out private.der

现在您拥有DER文件,您可以阅读它们在Java中使用 KeySpec KeyFactory 创建 PublicKey PrivateKey 对象。

  public byte [] readFileBytes(String filename)throws IOException 
{
路径路径= 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);
}

使用公钥和私钥,您可以加密和解密少量数据(适合您的RSA模数)。我推荐使用 OAEP 填充。

  public byte [] encrypt (PublicKey key,byte [] plaintext)throws NoSuchAlgorithmException,NoSuchPaddingException,InvalidKeyException,IllegalBlockSizeException,BadPaddingException 
{
加密密码= 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
{
密码密码=密码.getInstance( RSA / ECB / OAEPWithSHA1AndMGF1Padding);
cipher.init(Cipher.DECRYPT_MODE,key);
return cipher.doFinal(ciphertext);
}

这里用简单的加密和解密来捆绑:

  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 [] restored_message = decrypt(privateKey,secret);
System.out.println(new String(restored_message,UTF8));
}
catch(异常e)
{
e.printStackTrace();
}
}


I've been researching this for the past 4-5 hours now and can't seem to find an answer that actually works despite finding 'answers' that used everything from a few methods to an entire ~100 line class. I can't imagine that there isn't some simple function to do such a trivial thing :P

I have a pre-existing set of public / private keys (actually, two sets - one generated by ssh-keygen and another by openssl so .. whatever format works is cool).

All I am after is a simple java equivalent to what I write in python like -

key_object = someModule.KeyObject(nameOfPublicKeyFile)

def encrypt (SomePlainText) :
  return someOtherModule.encrypt(key_object, SomePlainText)

Any help would be awesome!

解决方案

These openssl commands in the shell create an RSA key pair and write the public and private keys to DER formatted files.

Here, the private key file is not password-protected (-nocrypt) to keep things simple.

$ 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

Now that you have the DER files, you can read them in Java and use KeySpec and KeyFactory to create PublicKey and PrivateKey objects.

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);     
}

With the public and private keys, you can encrypt and decrypt small amounts of data (that fit within your RSA modulus.) I recommend OAEP padding.

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);
}

Here it is tied together with a simple encryption and decryption:

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();
    }
}

这篇关于Java - 使用现有公钥文件加密字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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