java和openssl

cunj1qz1  于 2021-07-08  发布在  Java
关注(0)|答案(2)|浏览(823)

我需要帮助用openssl解密ecn加密文本的base64字符串。
在linux命令行中,我完成了以下操作:
生成公钥/私钥:

openssl genrsa -out private_key.pem 1024
openssl rsa -in private_key.pem -out public_key.pem -outform PEM -pubout

我的私钥.pem看起来像:

-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQDDu/0Fcq5/4M2t9Y+R4QvoDADQ+VaGSR3VEQiCV9xXcpkKAda+
nO2PrljIMcUO76O5a4twxxl1YT1dzKmj7T8i+EqYF1Y/1TxxWjIdo8hELD2Wug4d
ey3pMjI+5MXVraMyl5zEgfB64eTiu48LWygKi57Cfg41wKekSn2S/SvETQIDAQAB
AoGAFPgVwjioAyElR8av69PtP53RlJGxuE8q+AGMJNKe02t+g7jwtZkARk1KS6Ax
WUlJA/tGg/2Ad7fEKEFdxycKhVeF0ephOo8Xje6pMDDPpYSj/RlevUb60NEZZma1
PbA9TqS5Ys533jLYRbJUeNpufi0qQbRyB0QBJOUwbBHWDoECQQDsTYCoolsBHutY
YPZYBszOZhtxiDYqJ+B6/GoW/Y9h4HVg7CkKxaMdQBHbjTm+2YOH4SNHnwl7MVk3
cagbC/RhAkEA1AzKatUc7pUnkAO7VPM5luLnV/0ltpp6eveSgwxVs618a2BfFvS1
d8PAoKFCuCawTVd/GbY/fFKQab3hGiAXbQJBAOvIlZUukyG2KVzBO20wM9HK/p01
Ld64dXwiOvV/wj8GifjRDE7MT+rS0D7DVxhAz8aYdex0GzDKV9xD01pRfmECQBwi
9ljmnkgqEm3RkPHctC+JPBk4xeBM7yOR5ibtZBHLW08EIpnxLoMNvmmR/EBjIdGh
YoQO4q2kZvUg9NV6nKECQCFHa7lwlstxDqLgTzKHnRIK2hbUufrWKp+nDb18aqmF
eHvC4MZkixR+rykGRHsYjmwGKnXpbchKjC2iPFn1XY0=
-----END RSA PRIVATE KEY-----

我的公钥看起来像:

-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDDu/0Fcq5/4M2t9Y+R4QvoDADQ
+VaGSR3VEQiCV9xXcpkKAda+nO2PrljIMcUO76O5a4twxxl1YT1dzKmj7T8i+EqY
F1Y/1TxxWjIdo8hELD2Wug4dey3pMjI+5MXVraMyl5zEgfB64eTiu48LWygKi57C
fg41wKekSn2S/SvETQIDAQAB
-----END PUBLIC KEY-----

我可以使用public_key.pem创建base64字符串:

echo "Hola Mundo" | openssl rsautl -encrypt -pubin -inkey public_key.pem | base64 -w 0
gQO7XwvkClncfTpsv0jZ1Ptm2tI7YppHWdqwdrH2sZrG3ah5pcWt+PJ1q2ADPhZo8EURVmiYLO+q/P475/eUKY0h/T+IWQmV4lFCoXZfBzD3TzkN3nSmvj9HiR4psevYUa9HeOpECCXLJ1z8K4ut978zHtYKDi89k3VIdZUT6uY=

我可以使用private_key.pem解密字符串:

echo "gQO7XwvkClncfTpsv0jZ1Ptm2tI7YppHWdqwdrH2sZrG3ah5pcWt+PJ1q2ADPhZo8EURVmiYLO+q/P475/eUKY0h/T+IWQmV4lFCoXZfBzD3TzkN3nSmvj9HiR4psevYUa9HeOpECCXLJ1z8K4ut978zHtYKDi89k3VIdZUT6uY=" | base64 -d | openssl rsautl -decrypt -inkey private_key.pem

Hola Mundo

现在,我的问题是,在java中,像这样加载私钥:

String key = "MIICXAIBAAKBgQDDu/0Fcq5/4M2t9Y+R4QvoDADQ+VaGSR3VEQiCV9xXcpkKAda+\n" +
        "nO2PrljIMcUO76O5a4twxxl1YT1dzKmj7T8i+EqYF1Y/1TxxWjIdo8hELD2Wug4d\n" +
        "ey3pMjI+5MXVraMyl5zEgfB64eTiu48LWygKi57Cfg41wKekSn2S/SvETQIDAQAB\n" +
        "AoGAFPgVwjioAyElR8av69PtP53RlJGxuE8q+AGMJNKe02t+g7jwtZkARk1KS6Ax\n" +
        "WUlJA/tGg/2Ad7fEKEFdxycKhVeF0ephOo8Xje6pMDDPpYSj/RlevUb60NEZZma1\n" +
        "PbA9TqS5Ys533jLYRbJUeNpufi0qQbRyB0QBJOUwbBHWDoECQQDsTYCoolsBHutY\n" +
        "YPZYBszOZhtxiDYqJ+B6/GoW/Y9h4HVg7CkKxaMdQBHbjTm+2YOH4SNHnwl7MVk3\n" +
        "cagbC/RhAkEA1AzKatUc7pUnkAO7VPM5luLnV/0ltpp6eveSgwxVs618a2BfFvS1\n" +
        "d8PAoKFCuCawTVd/GbY/fFKQab3hGiAXbQJBAOvIlZUukyG2KVzBO20wM9HK/p01\n" +
        "Ld64dXwiOvV/wj8GifjRDE7MT+rS0D7DVxhAz8aYdex0GzDKV9xD01pRfmECQBwi\n" +
        "9ljmnkgqEm3RkPHctC+JPBk4xeBM7yOR5ibtZBHLW08EIpnxLoMNvmmR/EBjIdGh\n" +
        "YoQO4q2kZvUg9NV6nKECQCFHa7lwlstxDqLgTzKHnRIK2hbUufrWKp+nDb18aqmF\n" +
        "eHvC4MZkixR+rykGRHsYjmwGKnXpbchKjC2iPFn1XY0=";

包裹的绳子是这样装载的:

String data = "I3E5pjXE0chhtmkFBa56PGtWv5XDcIXfi2h5e3Bi44CCMvaIQ7UT7XBwkGZTRR11wfQIl7MswcEebXDmmw/C6JobrqQHQ0rU7zLPOU8j24JCFiccxclq5efMAcIO/ZcSO34uObrFQwQ4L2ex/3xL7b/YKujCQDTtzQkxE2N1JPU=";

我怎样才能找回原来的“hola mundo”字符串?你能给我指一下正确的方向吗?
先谢谢你。

sqougxex

sqougxex1#

您正在努力解决的问题是私钥的格式/编码。
您使用openssl生成了rsa密钥对,并收到了一个采用“旧”pkcs1编码的私钥,在pem字符串的开头可以清楚地看到:

-----BEGIN RSA PRIVATE KEY-----

不幸的是,java不能使用这种“开箱即用”的编码(您可以使用bouncy castle来读取这种密钥)。但是有一个解决方案,那就是将密钥转换为(支持java的)pkcs8编码。只需使用

openssl pkcs8 -topk8 -nocrypt -in rsaprivatekeypkcs1.pem -out rsaprivatekeypkcs8.pem

您将收到此私钥:

-----BEGIN PRIVATE KEY-----
MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAMO7/QVyrn/gza31
j5HhC+gMAND5VoZJHdURCIJX3FdymQoB1r6c7Y+uWMgxxQ7vo7lri3DHGXVhPV3M
qaPtPyL4SpgXVj/VPHFaMh2jyEQsPZa6Dh17LekyMj7kxdWtozKXnMSB8Hrh5OK7
jwtbKAqLnsJ+DjXAp6RKfZL9K8RNAgMBAAECgYAU+BXCOKgDISVHxq/r0+0/ndGU
kbG4Tyr4AYwk0p7Ta36DuPC1mQBGTUpLoDFZSUkD+0aD/YB3t8QoQV3HJwqFV4XR
6mE6jxeN7qkwMM+lhKP9GV69RvrQ0RlmZrU9sD1OpLliznfeMthFslR42m5+LSpB
tHIHRAEk5TBsEdYOgQJBAOxNgKiiWwEe61hg9lgGzM5mG3GINion4Hr8ahb9j2Hg
dWDsKQrFox1AEduNOb7Zg4fhI0efCXsxWTdxqBsL9GECQQDUDMpq1RzulSeQA7tU
8zmW4udX/SW2mnp695KDDFWzrXxrYF8W9LV3w8CgoUK4JrBNV38Ztj98UpBpveEa
IBdtAkEA68iVlS6TIbYpXME7bTAz0cr+nTUt3rh1fCI69X/CPwaJ+NEMTsxP6tLQ
PsNXGEDPxph17HQbMMpX3EPTWlF+YQJAHCL2WOaeSCoSbdGQ8dy0L4k8GTjF4Ezv
I5HmJu1kEctbTwQimfEugw2+aZH8QGMh0aFihA7iraRm9SD01XqcoQJAIUdruXCW
y3EOouBPMoedEgraFtS5+tYqn6cNvXxqqYV4e8LgxmSLFH6vKQZEexiObAYqdelt
yEqMLaI8WfVdjQ==
-----END PRIVATE KEY-----

是的,它看起来相等,但在一开始它只是“…开始私钥…”。
因为openssl端的默认rsa填充是pkcs1.5填充

openssl rsautl -help
-pkcs Use PKCS#1 v1.5 padding (default)

您应该在java端使用此示例:

Cipher decryptCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");

您将收到(使用pkcs8密钥)加密的字符串 Hola Mundo

frebpwbc

frebpwbc2#

有了“迈克尔·费尔”的帮助,我可以让它运转起来;这就是我所做的,以防别人需要它:
生成openssl pkcs8密钥对:

openssl genrsa -out keypair.pem 2048
openssl rsa -in keypair.pem -pubout -out publickey.crt
openssl pkcs8 -topk8 -inform PEM -outform PEM -nocrypt -in keypair.pem -out pkcs8.key

结果现在我有两个文件,publickey.crt:

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxlfy+juJwTDtw8XolfSK
QB+JaKTgZMl+MjWo+m9n8Kt64ygqtfGvDda1UvT3t9e2ZpOvlsmfSIN0SUMhsq+T
/O8+Xyr87/sUU7tYocQ6adGh+zO58EecuSUtgutDdwh9/WkVqHhdCjeZXN5310/s
afaxJJzBemMjvmc/1yiMtBSVrCl71CloR6J1lnz+QZK+zqaNlKIQdQay9PoQlGEL
RrGgqo8fHdK3OQVUd6Ifzh5G1Mmnv67esCAKyeW8yeb6lQ7dtsJQJEC8M9yn4n1D
bz0+OwWWTzqHBo8b5JYi6xXnb/0WsaRX/ooWk5BEykmkkBhSmDYx0ZtLZcA2/Pj2
jwIDAQAB
-----END PUBLIC KEY-----

和pkcs8.key:

-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDGV/L6O4nBMO3D
xeiV9IpAH4lopOBkyX4yNaj6b2fwq3rjKCq18a8N1rVS9Pe317Zmk6+WyZ9Ig3RJ
QyGyr5P87z5fKvzv+xRTu1ihxDpp0aH7M7nwR5y5JS2C60N3CH39aRWoeF0KN5lc
3nfXT+xp9rEknMF6YyO+Zz/XKIy0FJWsKXvUKWhHonWWfP5Bkr7Opo2UohB1BrL0
+hCUYQtGsaCqjx8d0rc5BVR3oh/OHkbUyae/rt6wIArJ5bzJ5vqVDt22wlAkQLwz
3KfifUNvPT47BZZPOocGjxvkliLrFedv/RaxpFf+ihaTkETKSaSQGFKYNjHRm0tl
wDb8+PaPAgMBAAECggEAWpirnI77cioWQJkyjuQ/DeEZ05mUAZVjti16fMHMWUsK
e53KPIcjbY/IDRdl2yyF3T7SMm7v+aBJynkGeGboktz4wWGSXU9zTnfBmUpXYCRn
96T95nnfZVZM/oLVsxZG7ixEv0oTPWp9+8SGOuv/0brj2RRc77k/B2aD65RTCKGc
iHMqK/mzeLedXrthaBwd0ppkQw1M6YvPw+nx8Mhs/sADKMLUTNkqpu16d+2pOLeU
DKsvnA8ns6/jfFMMdkJ3mhoIeCfqYJJhosydMebLnt8yUo/3NlNmeRKcqH9qx8zC
em+0wx9+a1fEgzPvadF1pnmI4n/5VlIn9moZXmO0MQKBgQDkg+4QqJT1upAg2NSQ
QMagoSECGoCM54aMpTCTDlhrzphW7tms5AjDmfrN/2NQ+LodjBHpqNd6E44D9U+6
EHBJ/PGOJE1CWdVckAUX+a51g67lmPNrfrFolTT1zrTJNq4VCKFffLUDW9yw+B+0
9QlWN36LG/jYr3Ia4D59mAgCRwKBgQDeMwTCJDfCMOPtiLT5Xl4J9H76aHU8por0
4C3fkq/zWCPxxU3XAO6eJQNzEhM8I+Yo/b3WbyzyqM2Ww9Y8qSOD/cpr2ftSdT60
l7jPSGjAIyudAd3QjkVC+OgwX1cSrfyuiRoyuQiHPyzAoiqK4AKxxUa0EFD8Ec42
X+mHT3eFeQKBgH13TmvJE9iDcYUHaFY3qpchQO1VvcUfjcmFHVFwq+2tRgldJRj/
LyyuS311PoODvTRh5qfjM0Psnqnfs8GWKwEEp2AC4ISQrEwhKxrJ1RbikVGwk94u
dpvUaHqZ3rsnkZcs4OV7pCtO8bIc2dPSQikbWRhp6EyYr86/1q/AnI0bAoGAb5G4
gu8CnFxGJkAtdsUefOsqUvveWhzZywlBn3AdLxgDvGMwqZOLPRciu0XJKLpx2AVI
rAJY1GNUD663xO+8qIrnd+4VFptOaAmCv3oBNvCx9n04bn7xYiZvF9LXesaoCM9I
u01Tbe2XwAXtTJwcXjzLOqCyuU8LdxwDu3B4eCkCgYEAsTQ8Rn6YaCy2cNl/7BZy
Jfr8tqwKprOeu+tcRg/MxUjjo72PVsK8WiahHHKxpFNlsDa0/u6GlICKUaY9Emul
Chu20kYr6xFFiczLo9enwiAJ5TDOz8yqOyv/1wALiTayOz2DVTwiax/D45yLJxQ6
dV0YXCvoOcDjM1c/vDVOK7w=
-----END PRIVATE KEY-----

现在,让我们使用publickey.crt文件将“hola mundo”加密为base64字符串:

echo "Hola Mundo" | openssl rsautl -encrypt -pubin -inkey publickey.crt | base64 -w 0
jeqdFnlj5Rxl8iQcoLc8o0u3KV4950OjSeqJW2ba0P5hcfdkIbtff/WW6rPdFudSYBOr1i+NwQ2jEpRGzOVrJ6mEZI4r/iFAJHkL7a3kQTs+pC1i5nig8MzO+5IU615HZhOykQ1FJfv3+OVOtTj8C5HLDZEehr1ggFPIp10YrYls6Gffxww5xlOZHBbg5J6JBmItmwFmvCl8O5ZI7N9hp5ynqqKYwAHxqRj0UUe1MXyGjEiL9aQdNiYJFCUL5V/0Vq6iP4sLRrU3Ir35fkMAWlQHt4vbmhgX5XUjv1804BIa7HlMytwnN7ZuKnJ6WKnOoJznpYbZOw92yXtKhPfUsA==

现在,通过使用bouncy castle库,java代码可以恢复“hola mundo”:

import java.io.File;
import java.io.FileReader;
import java.security.KeyFactory;
import java.security.interfaces.RSAPrivateKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;

import javax.crypto.Cipher;

import org.bouncycastle.util.io.pem.PemObject;
import org.bouncycastle.util.io.pem.PemReader;

public class App {
    public static RSAPrivateKey readPrivateKey(File file) throws Exception {
        KeyFactory factory = KeyFactory.getInstance("RSA");

        try (FileReader keyReader = new FileReader(file);
          PemReader pemReader = new PemReader(keyReader)) {

            PemObject pemObject = pemReader.readPemObject();
            byte[] content = pemObject.getContent();
            PKCS8EncodedKeySpec privKeySpec = new PKCS8EncodedKeySpec(content);
            return (RSAPrivateKey) factory.generatePrivate(privKeySpec);
        }
    }

    public static String getDecrypted(String data, RSAPrivateKey key) throws Exception {
        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");

        cipher.init(Cipher.DECRYPT_MODE, key);

        byte[] encryptedbytes = cipher.doFinal(Base64.getDecoder().decode(data.getBytes()));

        return new String(encryptedbytes);
    }

    public static void main(String[] args) {
        String data = "GjoUq7pz6ZV231MlZmBNiWnB7FlOHsGKFmAiMGhSUa9aIkXswnP8Ow4WTYR12tFIdyIeevQWCmEJgebiQ9wpBDLODtT4U00wTxPAfIjulgVhj0MA56b1nDkhCfL6gwzwsD2JxFO8/eMhqY1Wptn/fYn6USfbt7XFRyV73IeFBUvp0OisJ3DXxZsHfpfdL/yQcbGCboiiYEDkJ3DnLhGiaeMuLIedmABLgqWJv8EwPIBT0x/jgIMhaxQSwcs0w/fAYIEt/E4gkOpcFVkiTp6IKDsmiYgzDnXTnPko059Be9mQ3eJ3tIZ+U6Tfm1RCFY7Jr1oTIoZxOgHspgAIQb3U+w==";
        System.out.println("TEXTO CIFRADO:");
        System.out.println(data);
        System.out.println();

        try {
            File file = new File("/home/gbasisty/pruebas_openssl/pkcs8.key");
            RSAPrivateKey key = readPrivateKey(file);

            String texto = getDecrypted(data, key);
            System.out.println("TEXTO DESCIFRADO:");
            System.out.println(texto);
            System.out.println();
        } catch(Exception e) {
            System.out.println(e);
        }
    }
}

... 它就像一个魔咒。
再次感谢你,迈克尔!

相关问题