- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我需要为项目相关目的加密字符串,供应商为我提供了以下代码。
public static string EncryptString(string StringToEncrypt)
{
RSACryptoServiceProvider provider = new RSACryptoServiceProvider();
string xmlString = "<RSAKeyValue><Modulus>qqoWhMwGrrEBRr92VYud3j+iIEm7652Fs20HvNckH3tRDJIL465TLy7Cil8VYxJre69zwny1aUAPYItybg5pSbSORmP+hMp6Jhs+mg3qRPvHfNIl23zynb4kAi4Mx/yEkGwsa6L946lZKY8f9UjDkLJY7yXevMML1LT+h/a0a38=</Modulus><Exponent>AQAB</Exponent><P>20PwC7nSsfrfA9pzwSOnRYdbhOYivFSuERxvXHvNjCll5XdmFYYp1d2evXcXbyj3E1k8azce1avQ9njH85NMNQ==</P><Q>x0G0lWcQ13NDhEcWbA7R2W5LPUmRqcjQXo8qFIaHk7LZ7ps9fAk/kOxaCR6hvfczgut1xSpXv6rnQ5IGvxaHYw==</Q><DP>lyybF2qSEvYVxvFZt8MeM/jkJ5gIQPLdZJzHRutwx39PastMjfCHbZW0OYsflBuZZjSzTHSfhNBGbXjO22gmNQ==</DP><DQ>NJVLYa4MTL83Tx4vdZ7HlFi99FOI5ESBcKLZWQdTmg+14XkIVcZfBxDIheWWi3pEFsWqk7ij5Ynlc/iCXUVFvw==</DQ><InverseQ>X5Aw9YSQLSfTSXEykTt7QZe6SUA0QwGph3mUae6A2SaSTmIZTcmSUsJwhL7PLNZKbMKSWXfWoemj0EVUpZbZ3Q==</InverseQ><D>jQL4lEUYCGNMUK6GEezIRgiB5vfFg8ql3DjsOcXxnOmBcEeD913kcYnLSBWEUFW55Xp0xW/RXOOHURgnNnRF3Ty5UR73jPN3/8QgMSxV8OXFo3+QvX+KHNHzf2cjKQDVObJTKxHsHKy+L2qjfULA4e+1cSDNn5zIln2ov51Ou3E=</D></RSAKeyValue>";
provider.FromXmlString(xmlString);
return Convert.ToBase64String(provider.Encrypt(Encoding.ASCII.GetBytes(StringToEncrypt), false));
}
不过我需要修改或翻译成JAVA。我出于同样的目的编写了以下方法。
public static String EncryptString(String strToBeEncrypted) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidKeyException, UnsupportedEncodingException, IllegalBlockSizeException, BadPaddingException
{
String modulusString = "qqoWhMwGrrEBRr92VYud3j+iIEm7652Fs20HvNckH3tRDJIL465TLy7Cil8VYxJre69zwny1aUAPYItybg5pSbSORmP+hMp6Jhs+mg3qRPvHfNIl23zynb4kAi4Mx/yEkGwsa6L946lZKY8f9UjDkLJY7yXevMML1LT+h/a0a38=";
String publicExponentString = "AQAB";
byte[] modulusBytes = Base64.decodeBase64(modulusString);
byte[] exponentBytes = Base64.decodeBase64(publicExponentString);
BigInteger modulus = new BigInteger(1, modulusBytes);
BigInteger publicExponent = new BigInteger(1, exponentBytes);
RSAPublicKeySpec rsaPubKey = new RSAPublicKeySpec(modulus, publicExponent);
KeyFactory fact = KeyFactory.getInstance("RSA");
PublicKey pubKey = fact.generatePublic(rsaPubKey);
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1PADDING");
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
byte[] plainBytes = strToBeEncrypted.getBytes("US-ASCII");
byte[] cipherData = cipher.doFinal(plainBytes);
String encryptedStringBase64 = Base64.encodeBase64String(cipherData);
return encryptedStringBase64;
}
但样本结果不匹配。
字符串为“4111111111111111”,加密结果为:
PfU31ai9dSwWX4Im19TlikfO9JetkJbUE+btuvpBuNHTnnfrt4XdM4PmGA19z8rF+lPUC/kcOEXciUSxFrAPyuRJHifIDqWFbbJvPhatbf269BXUiAW31UBX3X5bBOqNWjh4LDitYY0BtarlTU4xzOFyb7vLpLJe9aHGWhzs6q0=
但是Java代码的结果是
Cxp5AIzTHEkrU6YWwYo5yYvpED2qg9IC/0ct+tRgDZi9fJb8LAk+E1l9ljEt7MFQ2KB/exo4NYwijnBKYPeLStXyfVO1Bj6S76zMeKygAlCtDukq1UhJaJKaCXY94wi9Kel09VTmj+VByIYvAGUFqZGaK1CyLnd8QXMcdcWi3sA=
最佳答案
为了提供语义安全,每个加密算法都需要随机化。否则,攻击者可能仅通过观察密文就注意到您再次发送了相同的消息。在对称密码中,此属性是通过随机 IV 实现的。在 RSA 中,这是通过随机填充实现的(PKCS#1 v1.5 类型 2 和 PKCS#1 v2.x OAEP 是随机的)。
您可以通过使用相同的 key 和明文再次运行加密并将密文与之前的密文进行比较来检查填充是否随机化。如果 C# 或 Java 中的密文在执行之间发生变化,那么您将无法仅通过查看密文来判断加密是否兼容。
检查这一点的正确方法是用一种语言加密某些东西,然后用另一种语言解密。为了完全兼容,您还应该尝试相反的方式。
看看你的代码,两者似乎是等价的,因为 false
作为第二个参数传递给 RSACryptoServiceProvider#Encrypt
以使用 PKCS#1 v1.5 填充,并且 Cipher.getInstance("RSA/ECB/PKCS1PADDING")
请求相同的填充。输入/输出编码似乎也是等价的。所以,是的,这段代码将是等效的。
现在不应使用 PKCS#1 v1.5 填充,因为它容易受到 Bleichenbacher 攻击 (reference)。您应该使用 OAEP 进行加密并使用 PSS 进行签名,这被认为是安全的。 C# 和 Java 都支持 OAEP,但使用的默认哈希函数(hash 和 MGF1)可能有所不同。
关于java - 将 C# RSACryptoServiceProvider 代码翻译成 Java,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36599453/
如果您查看下面的代码,它只是创建了一个 RSACryptoServiceProvider 的新实例。 key 容器名称是从一个属性初始化的,该属性根据各种参数创建名称。我在此演示代码中添加了硬编码值。
我需要使用 RSA 加密一些文本,然后使用私钥恢复它。我的问题是 RSACryptoServiceProvider.Encrypt() 每次都输出不同的值,即使使用相同的 key 也是如此。这是我放入
有人告诉我,对于非对称加密,您可以使用公钥加密明文并使用私钥解密。所以我尝试了以下方法: static void Main(string[] args) { RSACr
我在 MSDN( see Important note ) 上读到必须处理 RSACryptoServiceProvider。他们给出了例子: using (RSACryptoServiceProvi
我对商店的证书有疑问。在我的应用程序中,用户可以使用文件中的证书或商店中的证书。加载证书后,我使用证书作为签名数据。 可以使用文件中的证书,但我不能使用商店中的等效证书。 签名代码: // Sign
我正在使用 key 对对我的 XML 进行签名(使用 SignedXml),并将公钥作为嵌入式资源嵌入到我的应用中。 这里是我如何创建 key 对 sn -k Warehouse.snk sn -p
我有以下使用 RSA 生成公钥和私钥的代码。 // generate RSA 1024 using (var rsa = new RSACryptoServicePro
我正在尝试使用我自己的公钥和私钥初始化 RSACryptoServiceProvider。 据我所知,方法是调用构造函数 RSACryptoServiceProvider RSAalg = new R
我目前正在尝试创建一个 RSACryptoServiceProvider对象仅来自解码的 PEM 文件。经过几天的搜索,我确实设法解决了一个可行的解决方案,但它不是一个可以用于生产的解决方案。 简而言
我们正在导出公钥和私钥。私钥将由用 Magic 编写的非 .net 软件使用。开发人员对导出 key 的格式有疑问。是否有白皮书或其他资源来解释导出数据的格式? 最佳答案 关于导出的 blob 类型的
我有使用 RSACryptoServiceProvider 在 C# 中生成的公钥: 4kKhD/FWAMtQTRifArfXjxZN+6bOXTkHrVpyz/1wODhSOB
我有一个 X509Certificate2 变量,我正在尝试将该变量的私钥转换为 RSACryptoServiceProvider RSACryptoServiceProvider pkey = (R
我需要解密文本,但收到消息 The parameter is incorrect。 证书获取正确,已在 Windows 中注册。 在搜索问题时,我可以阅读建议更改分配给 IIS 网站的应用程序池中的用
我使用 RSACryptoServiceProvider 加密了一段文本。我导出了公钥和私钥。显然我只是想在解码器应用程序中公开公钥,所以我编写了如下代码: private const string
如果我有一个从非托管应用程序创建的 key ,并且如果我想将此 key 导入托管应用程序并生成另一个 key 或对其进行加密。基本上相同的 key 将从托管和非托管代码来回导入/导出。 因此什么相当于
这个问题在这里已经有了答案: 关闭 10 年前。 Possible Duplicate: Can RSACryptoServiceProvider (.NET’s RSA) use SHA256 f
一段时间以来,我一直在阅读 CodeProject 上的一篇文章,该文章解释了如何使用 RSA 提供程序进行加密和解密: RSA Private Key Encryption 虽然 2009 年的旧版
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.S
我正在尝试使用公钥加密与客户端和服务器进行通信。服务器应该生成一个 1024 位的公钥并将其发送给客户端,客户端将使用该 key 将加密数据发送回服务器。到目前为止,我已经用这个初始化了 RSACry
我目前正在处理一个简单的数据签名。这是我第一次使用签名,所以也许我做错了什么。但我认为使用 512 位 RSA 和 SHA1 哈希对 448 字节进行签名需要 4.6 秒是不正常的。 代码: byte
我是一名优秀的程序员,十分优秀!