简体   繁体   English

如何使用匹配的DER私钥解密公共PEM密钥加密的字节数组?

[英]How do I decrypt a public PEM key encrypted byte array using a matching DER private key?

So I am creating a basic socket program where I want to send an encrypted string in C to a Java program. 因此,我正在创建一个基本的套接字程序,我想在其中将C语言中的加密字符串发送到Java程序。 My C program encrypts the string with a public PEM key. 我的C程序使用公共P​​EM密钥加密字符串。 I have converted the matching private PEM key to a DER key and now want to decrypt the string that was sent to my Java program. 我已经将匹配的专用PEM密钥转换为DER密钥,现在想解密发送给Java程序的字符串。 How do I do this? 我该怎么做呢?

At the moment I am getting an IllegalBlockSizeException stating that "Data must not be longer than 256 bytes" when trying to run the code as it stands. 目前,我收到一个IllegalBlockSizeException声明,尝试按原样运行代码时,“数据不得超过256个字节”。

This is what I have at the moment: 这是我目前所拥有的:

C client program... C客户端程序...

 //Get our public key from the publickey file created by server
    FILE *publicKeyFile = fopen("publicKey.pem", "rb");
    RSA *rsa = RSA_new();
    rsa = PEM_read_RSA_PUBKEY(publicKeyFile, &rsa, NULL, NULL);
    if(rsa == NULL) {
            printf("Error with public key...\n");
    }
    else {
            //if the public key is correct we will encrypt the message
            RSA_public_encrypt(2048, sigMessage, sigMessage, rsa, RSA_PKCS1_PADDING);
    }

Java decryption... Java解密...

    public static String decrypt(byte[] encryptedMessage) {

    try {
        Cipher rsa;
        rsa = Cipher.getInstance("RSA");
        PrivateKey ourKey = getKey("resources/privateKey.der");
        rsa.init(Cipher.DECRYPT_MODE, ourKey);
        byte[] utf8 = rsa.doFinal(encryptedMessage);
        return new String(utf8, "UTF8");
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

public static PrivateKey getKey(String filePath) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {

        File f = new File(filePath);
        FileInputStream fis = new FileInputStream(f);
        DataInputStream dis = new DataInputStream(fis);
        byte[] keyBytes = new byte[(int) f.length()];
        dis.readFully(keyBytes);
        dis.close();

        PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory kf = KeyFactory.getInstance("RSA");
        return kf.generatePrivate(spec);
    }

You can't encrypt 2,048 bytes with RSA unless you have an RSA key of over 16K. 除非您的RSA密钥超过16K,否则无法使用RSA加密2,048 字节 You probably have a 2048 bit RSA key, which limits you to under 256 bytes. 您可能有一个2048 RSA密钥,它将您限制在256个字节以下。 Check out the openssl man page for RSA_public_encrypt : 查看RSA_public_encrypt的openssl手册页:

flen must be less than RSA_size (rsa) - 11 for the PKCS #1 v1.5 based padding modes, less than RSA_size(rsa) - 41 for RSA_PKCS1_OAEP_PADDING and exactly RSA_size(rsa) for RSA_NO_PADDING. 对于基于PKCS#1 v1.5的填充模式,flen必须小于RSA_size (rsa)-11;对于RSA_PKCS1_OAEP_PADDING,小于RSA_size(rsa)-41;对于RSA_NO_PADDING,小于RSA_size(rsa)。 The random number generator must be seeded prior to calling RSA_public_encrypt(). 必须在调用RSA_public_encrypt()之前为随机数生成器添加种子。

And RSA_size : RSA_size

RSA_size() returns the RSA modulus size in bytes . RSA_size()返回以字节为单位的RSA模数大小。 It can be used to determine how much memory must be allocated for an RSA encrypted value. 它可用于确定必须为RSA加密值分配多少内存。

You should not encrypt a full 256 bytes with a 2048 bit key, though. 但是,您不应该使用2048位密钥加密完整的256个字节。 You want to always use random padding with RSA encryption, and choose OAEP over v1.5. 您希望始终将随机填充与RSA加密一起使用,并选择OAEP而不是v1.5。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM