使用Ruby生成的RSA public.pem文件在Android中加密数据

dum*_*ll3 4 ruby encryption android pem public-key

很抱歉问一个特定的问题,但是我需要在java代码中生成一个'签名',就像ruby中的以下代码行一样:

signature = OpenSSL::PKey::RSA.new(File.read("PUBLIC_PEM_PATH")).public_encrypt('SECRET_KEY')

我有.pem密钥文件和SECRET_KEY,它是这样的:F6qxlwQTYWRM3gRfgftryKJHKYZiGXdoy5lDm4

我怎样才能做到这一点 ?

谢谢!

更新1 我试过这个:

File pubKeyFile = new File(keyFileName);
    DataInputStream inputStream;
    byte[] signature = null;
    try {
        inputStream = new DataInputStream(new FileInputStream(pubKeyFile));
        byte[] pubKeyBytes = new byte[(int)pubKeyFile.length()];
        inputStream.readFully(pubKeyBytes);
        inputStream.close();

        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        X509EncodedKeySpec pubSpec = new X509EncodedKeySpec(pubKeyBytes);
        RSAPublicKey pubKey = (RSAPublicKey) keyFactory.generatePublic(pubSpec);

        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        cipher.init(Cipher.ENCRYPT_MODE, pubKey);

        signature = cipher.doFinal(secretKey.getBytes());
    } catch (Exception e) {
        e.printStackTrace();
    }
    return signature;
Run Code Online (Sandbox Code Playgroud)

并得到这个错误:

java.security.spec.InvalidKeySpecException: java.lang.RuntimeException: error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag
Run Code Online (Sandbox Code Playgroud)

UPDATE2 我设法从.pem文件加载公钥.但是现在,我从密码中得到了一个错误.

public static byte[] getSignature(String keyFileName, byte[] secretKey){
    byte[] signature = null;
    try {
        PublicKey pubKey = readKeyFromFile(keyFileName);
        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        cipher.init(Cipher.ENCRYPT_MODE, pubKey);

        signature = cipher.doFinal(secretKey);
    } catch (Exception e) {
        e.printStackTrace();
    }
    return signature;
}
private static PublicKey readKeyFromFile(String keyFileName) throws IOException {
    InputStream in = new FileInputStream(keyFileName);
    DataInputStream din = new DataInputStream(in);
    try {
        BigInteger m = BigInteger.valueOf(din.readLong());
        BigInteger e = BigInteger.valueOf(din.readLong());
        RSAPublicKeySpec keySpec = new RSAPublicKeySpec(m, e);
        KeyFactory fact = KeyFactory.getInstance("RSA");
        RSAPublicKey pubKey = (RSAPublicKey) fact.generatePublic(keySpec);
        return pubKey;
    } catch (Exception e) {
        throw new RuntimeException("Spurious serialisation error", e);
    } finally {
        din.close();
    }
}
Run Code Online (Sandbox Code Playgroud)

错误日志:

javax.crypto.IllegalBlockSizeException: input must be under 8 bytes
Run Code Online (Sandbox Code Playgroud)

有什么想法吗??

dum*_*ll3 6

最后,经过数小时的研究后,我找到了一个解决方案,最后可以从.pem文件中读取我的公钥并生成此密钥的实例.因此,我设法加密数据.

但是我必须复制并粘贴关键内容而不使用任何特殊字符,例如'\n',然后publicKeyString使用它

---------- BEGIN RSA PUBLIC KEY ---------

关键内容

---------- END RSA PUBLIC KEY ---------

static public PublicKey publicKey(String publicKeyString) {
    try {
        byte[] decodedPublicKey = Base64.decode(publicKeyString, 0);
        ASN1InputStream in = new ASN1InputStream(decodedPublicKey);
        ASN1Primitive obj = in.readObject();
        RSAPublicKeyStructure keyStruct = RSAPublicKeyStructure.getInstance(obj);
        RSAPublicKeySpec keySpec = new RSAPublicKeySpec(keyStruct.getModulus(), keyStruct.getPublicExponent());
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        return keyFactory.generatePublic(keySpec);
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch (InvalidKeySpecException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return null;
}
Run Code Online (Sandbox Code Playgroud)

即使我试图使用充气城堡的PEMReader,我也失败了.所有这些问题都与之前的Ruby版本1.9.3中生成的密钥有关,详见此处.

无论如何,非常感谢关注.