我用RSA加密来加密C#中的一些数据。现在我想用Java解密加密的数据。但是我遇到了一些问题。
主要问题可能是将加密消息从c#获取到java。在c#中,我们有无符号字节,字节序是不同的
因此,为了进行测试,我将c#中加密数据的byte
数组转换为sbyte
数组并获得它的字符串表示形式。然后我将字节数组的字符串表示形式复制到我的java代码中并将其转换回“字节”数组。之后,我反转数组以匹配java的endianess。
但是,如果我尝试解码上面传输的数据,我会得到以下异常:
javax.crypto.BadPaddingException:Message is large than modulus
从C#到C35的加密和解密与从java到java一样有效。只有C#到java不能工作。(要加密的字符串的长度为7个字符,因此它并不太长)
我正在将c#中的公钥转换为<code>BigInteger</code>。公钥由<code>参数</code>传递:
html" target="_blank">public byte[] RSAEncrypt(byte[] data, RSAParameters param, bool padding) {
using (RSACryptoServiceProvider rsaProvider = new RSACryptoServiceProvider(1024)) {
rsaProvider.ImportParameters(param);
byte[] modulusArray = param.Modulus;
byte[] exponentArray = param.Exponent;
BigInteger modulusBigInt = new BigInteger(modulusArray);
BigInteger exponentBigInt = new BigInteger(exponentArray);
encryptedData = rsaProvider.Encrypt(data, false);
return encryptedData;
}
}
之后,我将模数和指数的字符串表示形式复制到我的java代码中,并从中创建新的BigInteger
并创建公钥:
BigInteger modulusBigInt = new BigInteger(modulusBytesStr);
BigInteger exponentBigInt = getBigIntFromByteString(exponentBytesStr);
Key pK = getPublicKey(modulusBigInt, exponentBigInt);
然后我尝试解密数据(其中数据是我从c#传输到java的字节数组,如上所述):
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, pK);
decryptedData = cipher.doFinal(data);
但是如果我尝试这样做,我得到了上面提到的异常。我认为公钥应该是正确的。至少我在c#和java中的模和指数的BigIntger
值相同。填充也是相等的。所以我假设我的加密数据的格式有问题。它应该有哪个版本?
我也看过这个问题:RSA。NET加密Java解密,但即使这样,我也不确定我要加密/解密的数据应该是什么格式
EDIT:试图将c#中的加密字节转换为< code>Base64字符串并在java中将其转换回字节。也不起作用
EDIT2:如果我使用var key = rsaProvider.ToXmlString(true);
要获取公钥的xml重现,并将模数和指数的xml字符串放在我的java代码中,将它们从Base64字符串转换为字节数组,从字节数组转换为BigInteger,那么我将获得模量的BigInteger的另一个值,就像BigInteger在c#中一样, 但是我得到这个值的异常:javax.crypto.BadPaddingException:解密错误
编辑3:发现我的错误:为了简单的测试,我只是使用我在C#代码中生成的私钥在java中解密。但在我的java代码中,我尝试从私钥生成公钥。
RSAPublicKeySpec keySpec = new RSAPublicKeySpec(modulus, exponent);
KeyFactory kf = KeyFactory.getInstance("RSA");
PublicKey pK = kf.generatePublic(keySpec);
这显然是错误的。所以我把它改成了:
RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(modulusBigInt, exponentBigInt);
KeyFactory kf = KeyFactory.getInstance("RSA");
Key key = kf.generatePrivate(keySpec);
它成功了。这也是GregS方法工作的原因(没有生成“PublicKey”或“PrivateKey”,并且解密不是使用的java内置方法)
因此,为了测试,我将c#中加密数据的字节数组转换为sbyte数组,并获得它的字符串表示。然后,我将字节数组的字符串表示复制到我的java代码中,并将其转换回“字节”数组。之后,我反转数组来匹配java的字节序。
我不太明白为什么“字节序”在这里是一个问题。字节序是运行 CPU 的函数,而不是编程语言。
我有点不清楚你到底哪里错了。下面是一个对我有用的示例,我基于您的代码。我没有Windows机器,所以我在Mono中测试了这个。
C#:
using System;
using System.Security.Cryptography;
using System.Text;
namespace RsaDotNetToJava
{
class MainClass
{
public byte[] RSAEncrypt(byte[] data, RSAParameters param, bool padding) {
using (RSACryptoServiceProvider rsaProvider = new RSACryptoServiceProvider(1024)) {
rsaProvider.ImportParameters(param);
var encryptedData = rsaProvider.Encrypt(data, false);
return encryptedData;
}
}
public static void W(string label, byte [] x) {
var b64 = Convert.ToBase64String (x);
Console.WriteLine ("{0} = {1}", label, b64);
}
public static void Main (string[] args)
{
var x = new MainClass ();
var rsa = new RSACryptoServiceProvider (1024);
var data = Encoding.ASCII.GetBytes("Hello world");
var parms = rsa.ExportParameters(true);
W ("Modulus", parms.Modulus);
W ("P", parms.P);
W ("DecryptExponent", parms.D);
W ("EncryptExponent", parms.Exponent);
var cipher = x.RSAEncrypt(data, parms, false);
W ("Cipher", cipher);
}
}
}
接下来,一些 Java 从命令行读取 base64 字符串(“label = ” 剥离)并执行一些操作。这使用java 7类javax.xml.bind.DatatypeConverter
作为其base64解析器。
import java.math.BigInteger;
import javax.xml.bind.DatatypeConverter;
public class RsaJavaToDotNet {
private static BigInteger b64ToBigInteger(String b64) {
byte [] bigEndianBytes = DatatypeConverter.parseBase64Binary(b64);
return new BigInteger(1, bigEndianBytes);
}
/**
* @param args base64 encoded .NET big-endian integer arrays
* args[0] = modulus
* args[1] = prime
* args[2] = decrypt exponent
* args[3] = encrypt exponent
* args[4] = cipher
* @throws Exception
*/
public static void main(String[] args) throws Exception {
BigInteger modulus = b64ToBigInteger(args[0]);
final int modulusByteLength = (modulus.bitLength() + 7) / 8;
BigInteger prime = b64ToBigInteger(args[1]);
BigInteger d = b64ToBigInteger(args[2]);
BigInteger e = b64ToBigInteger(args[3]);
BigInteger cipherInt = b64ToBigInteger(args[4]);
// Decrypt the cipher
BigInteger plainInt = cipherInt.modPow(d, modulus);
byte [] plain = plainInt.toByteArray();
// Verify the format and extract the message.
if (plain.length != (modulusByteLength - 1) || plain[0] != 2) {
throw new Exception("Something is wrong");
}
// Find the zero byte delimited the payload from the padding
int zeroPos = 1;
while (zeroPos < plain.length && plain[zeroPos] != 0) {
++zeroPos;
}
String plainStr = new String(plain, zeroPos + 1, plain.length - zeroPos - 1, "UTF-8");
System.out.println(plainStr);
}
}
我正在尝试在我的C#程序中实现RSA加密。 这是我的代码: 我收到这个错误代码: <代码>系统。安全密码学。CryptographicException:“错误数据。” 这一行给出了错误:
本文向大家介绍java使用RSA加密方式实现数据加密解密的代码,包括了java使用RSA加密方式实现数据加密解密的代码的使用技巧和注意事项,需要的朋友参考一下 RSA的应用 RSA是一种非对称加密算法。现在,很多登陆表单的密码的都采用RSA加密,例如京东中的登陆使用公钥对密码进行加密 java使用RSA加密方式实现数据加密解密,需要首先产生私钥和公钥 测试代码 RSA工具类的实现 总结 以上所述是
前面小节介绍了如何存储密码,但是有的时候,我们想把一些敏感数据加密后存储起来,在将来的某个时候,随需将它们解密出来,此时我们应该在选用对称加密算法来满足我们的需求。 base64加解密 如果Web应用足够简单,数据的安全性没有那么严格的要求,那么可以采用一种比较简单的加解密方法是base64,这种方式实现起来比较简单,Go语言的base64包已经很好的支持了这个,请看下面的例子: package
在C#中解密RSA加密字符串时,我得到的错误是,要解密的数据超过了256字节模的最大值。 我正在努力实现的目标: 在C#(RSA)中生成公钥/私钥对 将私钥保存在会话/临时存储中,以便在解密期间使用 向客户端/JS发送/返回公钥以用于加密 用公钥加密JS中的字符串(最多20个字符)并发送到服务器 使用步骤2中保存的私钥解密服务器中加密的字符串 工作原理: 公钥/私钥对的生成 在JS中使用库jscr
问题内容: 我正在尝试使用RSA算法在.NET中加密字符串,并在Java中解密结果。目前,我已经可以做相反的事情(用Java加密,用.NET解密)。这里有我的代码可以实际工作(JAVA加密): 和(.NET解密) 现在我想做相反的事情……但是我遇到了一些错误,例如(密钥的大小应该是128个字节……等等)我应该怎么做? 在这里,我添加当前的 无效 代码: 。净 爪哇 问题答案: Java解密代码的最
问题内容: 我正在使用RSA在JAVA上进行加密,并尝试使用.NET进行解密。我包括我的JAVA代码和.NET代码,希望有人对此有所了解。 JAVA代码: 从此JAVA代码中,我得到了加密字符串的结果,该结果恰好是: FOP4 AAIH6hcabXnrvNG5YUk + / + nBv9n9HU0CAgZjkIWQIDjbOpSwoPVBFERrZ6641x2QaoJw5yv18XAay 0WrC