2012-05-21 185 views
2

我们有一个.Net应用程序,用于加密和解密文本并将其存储在数据库中。我发现.Net开发人员已将RSA密钥存储为XML格式。当他们与加密完成的文本存储在具有以下模式的数据库:.Net RSA加密,Java RSA解密

0D-E4-1D-91-44-2B-B5-3B-03-34...and so on (total of 383 characters) 

我们移植现有.NET应用程序的Java平台。为此,我想使用现有的编码数据进行解码。

我已经用Java编写下面的代码(复制从互联网粘贴 - 我没有关于RSA的任何理解或任何形式的加密的)

public String decryptText (byte[] encryptedText) throws Exception { 

    String decryptedText = null; 

    if (rsaData != null) { 
     byte[] modBytes = Base64.decodeBase64(rsaData.getModulus().trim()); 
     byte[] dBytes = Base64.decodeBase64(rsaData.getD().trim()); 

     BigInteger modules = new BigInteger(1, modBytes); 
     BigInteger d = new BigInteger(1, dBytes); 

     KeyFactory factory = KeyFactory.getInstance("RSA"); 
     Cipher cipher = Cipher.getInstance("RSA"); 

     RSAPrivateKeySpec privSpec = new RSAPrivateKeySpec(modules, d); 
     PrivateKey privKey = factory.generatePrivate(privSpec); 
     cipher.init(Cipher.DECRYPT_MODE, privKey); 
     byte[] decrypted = cipher.doFinal(encryptedText); 

     decryptedText = new String(decrypted); 

    } 

    return decryptedText; 
} 

其中保存XML数据rsaData =参考。我的XML看起来是这样的:

<RSAKeyValue> 
<Modulus> 
    ynKHV6Tm/tV7ZsTRMLNjMqlAkbftMXA/OkM5zi6+ih371Jgi6ZNX2T4ml0DmK1hojwumHadiX3YoPlaJ/xiys4NRxbDH9VuJJeTdZvoB8heKxACaIw9l1CCTEkx3jYVJ+h6M10fV3wChD0BOtiLg3rMO64LpR2DAGZNbVjXL3h0= 
</Modulus> 
<Exponent>AQAB</Exponent> 
<P>5QUpIuwCOqR03GqI0K7Y4yWn0hvYa7b9RkCA9Y1QQ0IyBqfiTYOT87cKBRsu4FxH6tdY0khfFCskFgumx22gOw==</P> 
<Q>4kv69rnEMxSOzmg4ZkAuxrUc6wZCuIJAgSL9gGBFukQSIB6UVWXYhNUDzklcMtGE/lRmwJvwSIlpZBlVtlYthw==</Q> 
<DP>ae7LKlYUad+sFlBI3I4j0F2YlL1AjAJmgNpRTEODPrkdvqplKQmVpAOkZNxAAJNuyJe3g/zpzcBuvqvBBzoUBQ==</DP> 
<DQ>M+iL27aG+9SWYWBkt4e3cxsuU/burRYrp7OYBK+QrwZYRgfdrK0c+nNGWTZYsMuAvzorC7l5Z5olk7GACMBB1w==</DQ> 
<InverseQ> 
    UuLEf34YsvFxzgzKhdONvFhsSDRleC5rPR/XvpJl9NEikwXQHTr4547hYM+4soHRdBaiUFdzNtxLMlRW481L1A== 
</InverseQ> 
<D> 
    aNSFYMzzEGJbVAv2htFdPI6H8Ozc1gzZsMG+3RU3dS2xiZR9/5VcmBGmygvBJBDTk77kddaHCgeVLzKAoqeXYJGJgiNQgByE+jQz70HkOaAy0muNbAxLOk9UY6lkJ9kVbtSu1LyR83yj4+kSGNo4T63LBKV07TirAhDMJAk3o8E= 
</D> 
</RSAKeyValue> 

当我打电话通过传递编码的文本,我得到了以下错误decryptText()方法:

Exception in thread "main" javax.crypto.IllegalBlockSizeException: Data must not be longer than 128 bytes 
at com.sun.crypto.provider.RSACipher.a(DashoA13*..) 
at com.sun.crypto.provider.RSACipher.engineDoFinal(DashoA13*..) 

是否有人可以解决此问题的帮助?或者指向一些有用的链接?


所以挣扎了几个小时后,我做了以下内容:

我在decryptText()方法更新两条线如下:

KeyFactory factory = KeyFactory.getInstance("RSA"); 
Cipher cipher = Cipher.getInstance("RSA/ECB/NOPADDING"); 

我意识到加密的字符串是十六进制编码,所以我扭转回来。所以原始的字符串(去掉破折号后)的:

1322829145684318159352601201165341161130212111239120172192552382321681005365571520823020721395242114149106119101747920169161831211748781201152821423521012222201691166150158120221052590252851921052281199918638104578159158115138861911531100176209133541522422481711310198179214164975320920468140732925421720220119120115314722510613321 

此后反向六角变成了:

ä?D+µ;4<xt5)¡?Ôoïx¬ÿîè¨d5A9?æÏÕ_òr?jw®OÉE·y0Nx?ÖëÒ?©???xiZüUÀiäwcº&hN??s?V¿?d°Ñ?6?òø«Æ?Ö?a5ÑÌD?I?ÙÊÉ¿É??áj? 

我通过这串到我上面decryptText()方法。我期待一个经常理智的人类可读字符串被打印回来,但我得到了以下字符串:

&LÑP źç–4õ∂Ôı)¬' Ó.fi—Ø€Âótiø?R”ÀNQ°≥Y¶B˚w»Rüaûr>Vœ&˙◊@Ë¡.e¿–5 ÉP3ŒJjü&è˛LCÔ@Ÿ$‰=êyôázwQå{<7 ŸR‘BîóÅWÎhŸyÈ[èR 

所以任何人谁可以帮助我?

回答

1

@MartinErnst最后我得到了我的答案。我使用了Bouncy Castle图书馆并将我的代码更新为以下内容:

Security.addProvider(new BouncyCastleProvider()); 

    DuncanCipherSecond cipherSecond = new DuncanCipherSecond(); 

    RSAKeyXMLReader rsaKeyXMLReader = new RSAKeyXMLReader(); 
    InputStream inputStream = new ByteArrayInputStream(rsaKeyInXMLString.getBytes()); 
    RSAData rsaData = rsaKeyXMLReader.parse(inputStream); 

    if (rsaData != null) { 
     byte[] expBytes = Base64.decodeBase64(rsaData.getExponent().trim()); 
     byte[] modBytes = Base64.decodeBase64(rsaData.getModulus().trim()); 
     byte[] dBytes = Base64.decodeBase64(rsaData.getD().trim()); 


     String nameFromDB = "8B-FE-BE-28-27-94-0B-32-CE-86-24-9E-F1-DA-86-0F-E1-31-B7-2B-7A-58-2C-E2-3A-6F-05-E9-40-70-48-1D-73-6B-30-E5-95-B9-2A-8A-3F-6E-66-94-DF-8F-7C-11-77-C6-A1-E9-09-04-3B-19-C2-AF-19-CE-EE-22-A3-F9-17-D5-C8-C5-9F-12-F2-C5-72-25-D6-C3-D9-4B-E0-E5-46-19-27-80-9A-11-EC-0F-85-4D-13-0B-94-DB-1B-64-21-95-68-7B-A3-C9-1B-AA-94-E7-26-48-49-BA-CD-97-9D-41-23-1E-B6-F9-26-3C-1E-67-84-98-83-A7-3C-06"; 
     nameFromDB = nameFromDB.replace("-", ""); 

     byte[] newNameFromDB = hexStringToByteArray(nameFromDB); 

     BigInteger modules = new BigInteger(1, modBytes); 
     BigInteger exponent = new BigInteger(1, expBytes); 
     BigInteger d = new BigInteger(1, dBytes); 

     KeyFactory factory = KeyFactory.getInstance("RSA"); 
     Cipher cipher = Cipher.getInstance("RSA/None/OAEPWithSHA1AndMGF1Padding", "BC"); 

     System.out.println(""); 
     RSAPrivateKeySpec privSpec = new RSAPrivateKeySpec(modules, d); 
     PrivateKey privKey = factory.generatePrivate(privSpec); 
     cipher.init(Cipher.DECRYPT_MODE, privKey); 
     byte[] decrypted = cipher.doFinal(newNameFromDB); 
     System.out.println("decrypted: " + new String(decrypted));