2014-02-21 23 views
4

不好意思问一个具体的问题,但我需要在Java代码中生成一个像红宝石下面的代码行“签名”:加密数据与红宝石生成的RSA public.pem文件

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; 

而得到这个错误:

java.security.spec.InvalidKeySpecException: java.lang.RuntimeException: error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag 

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

错误日志:

javax.crypto.IllegalBlockSizeException: input must be under 8 bytes 

有什么想法?

+0

使用Signature类。 – EJP

+1

这看起来不像签名方案。你有什么要求? – Henry

+0

“要求”是什么意思?我只是想用Java生成'签名'。 – dum4ll3

回答

6

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

但我不得不与它

---------- BEGIN RSA公共密钥 - 复制并粘贴重点内容没有像“\ n”的任何特殊字符,并作出publicKeyString --------

重点内容

---------- END RSA公钥---------

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

即使我尝试使用弹跳城堡中的PEMReader,我也失败了。所有的问题都与Ruby 1.9.3之前生成的密钥有关,详情请参阅here

无论如何,非常感谢处理的关注。

+0

感谢您的解决方案,rferraz(+1) –

+0

非常感谢和平的人。我很高兴! – Gavjr

1

看起来像密钥包装(加密)给我。使用弹性城堡阅读PEM文件,然后使用Cipher.getInstance("RSA/ECB/PKCS1Padding")加密密钥,然后使用base 64对结果进行编码...您也可以尝试模式Cipher.WRAP_MODE以查看是否有效。请注意,加密将始终返回不同的结果,测试兼容性的唯一方法是使用其他软件对其进行解密。

+0

您是否介意提供有关此过程的更多详细信息?我可以理解一点,但仍然怀疑您提出的实施方案。另外,如果可能,我想避免使用第三部分库。 thaks – dum4ll3

+0

关于第二个问题,如果您有PEM,那么您需要自己解码包含在PEM中的数据,或者您必须使用第三方库,因为该功能没有(正式)包含在Java API中。它可能是Sun实现的某个地方,但除非你希望你的应用程序在将来崩溃,否则你绝对不应该使用它们。 –