我需要将私钥中的加密字符串发送到key服务器进行身份验证。我有正确生成加密字符串的Java客户端代码(这样key服务器就可以用公钥解密它)。我正在尝试编写C#代码来执行完全相同的加密-但没有成功。
首先,在java中使用keytool生成一个密钥库,如下所示:
keytool -genkey -dname "cn=Application Test, ou=XXX, o=YYY, c=US" -alias AppTest -keypass AppTest -keystore AppTest.jks -storepass AppTest -validity 1800 -keyalg RSA然后,这段java代码正确地读取密钥库并加密数据(privateKey.getAlgorithm()返回"RSA"):
KeyStore ks = KeyStore.getInstance("JKS");
InputStream is = new FileInputStream("AppTest.jks");
ks.load(is, "AppTest".toCharArray());
is.close();
PrivateKey privateKey = (PrivateKey) ks.getKey(user, password.toCharArray());
// Encrypt with the private key
String stamp = "123456";
byte[] bytesStampUtf8Unencrypted = stamp.getBytes(Charset.forName("UTF-8"));
Cipher cipher = Cipher.getInstance(privateKey.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
byte[] bytesTimestampUtf8Encrypted = cipher.doFinal(bytesStampUtf8Unencrypted);
String encrypted = new String((new Base64()).encode(bytesStampUtf8Unencrypted));当传递给web服务时,这一切都工作得很好。然后我使用keytool将java密钥库转换为在我的.NET应用程序中使用的PKCS12证书:
keytool -importkeystore -srckeystore AppTest.keystore -destkeystore KEYSTORE.p12 -srcstoretype JKS -deststoretype PKCS12 -srcstorepass AppTest -deststorepass AppTest-srcalias AppTest -destalias AppTest -srckeypass AppTest -destkeypass AppTest -noprompt我使用keytool比较了keystore和P12文件的指纹--完全相同。我认为下面的C#代码应该可以工作:
X509Certificate2 myCertificate =
new X509Certificate2(@"C:\Temp\KEYSTORE.p12", "AppTest");
RSACryptoServiceProvider privateKey =
myCertificate.PrivateKey as RSACryptoServiceProvider;
String stamp = "123456";
byte[] buffer = Encoding.UTF8.GetBytes(stamp);
byte[] encryptedBytes = privateKey.Encrypt(buffer, false);
String encrypted = Convert.ToBase64String(encryptedBytes);它正确地读取转换后的keystore文件,执行时没有问题,并生成看似加密的数据,但web服务不喜欢加密的字符串(无法使用公钥解密)。当我将C#加密串替换为Java加密串(在调试器中)并通过C#程序将该串发送到web服务时-一切都工作得很好-所以我确信问题出在加密过程中,而不是web服务通信中。
我无法控制原始密钥的生成方式(作为java密钥库),也无法控制web服务所期望的加密方法。我只能控制与基于Java的web服务交互的.NET客户端。
我是不是遗漏了一些标志,设置,变量,什么?
发布于 2010-03-05 06:55:47
您确定与java实现相比,加密算法、块密码模式和填充模式在C#实现中是等效的吗?
编辑:实际上,对于RSACryptoProvider,您可能不需要密码/填充模式-看看MSDN上的示例,特别是关于通过ImportParameters导入公钥信息的部分
发布于 2011-06-04 00:26:41
这是一个在工作条件下很难找到的解决方案,在Java中加密,在.Net中解密,最终我能够在我的一个项目中实现,使用它我们可以在java中加密任何字符串,并在.Net端使用BouncyCastle API解密。
我已经使用Blowfish进行了加密/解密:
你可以从以下网址查阅bouncycastle的文件:http://bouncycastle.org/latest_releases.html
Java代码
import org.bouncycastle.util.encoders.UrlBase64;
import org.bouncycastle.crypto.engines.BlowfishEngine;
import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.util.Strings;
public class EncryptString
{
public static void main(String[] args) throws Exception
{
String plain = "UserName=\'pgupta\'&Channel=\'1\'&LevelID=\'1\'&LevelName=\'Super Star colony\'";
String key = "x-392kla%3$*1f";
//To getBytes in UTF8 Encoding
byte[] inBytes = plain.getBytes("UTF8");
byte[] keyByte = key.getBytes("UTF8");
PaddedBufferedBlockCipher _cipher = new PaddedBufferedBlockCipher(new BlowfishEngine());
try
{
_cipher.init(true, new KeyParameter(keyByte));
// Determine the minimum output buffer size
byte[] outBytes = new byte[_cipher.getOutputSize(inBytes.length)];
// 'len' is the actual size returned
int len = _cipher.processBytes(inBytes, 0, inBytes.length, outBytes, 0);
_cipher.doFinal(outBytes,len);
System.out.println("encrypted: " + new String(UrlBase64.encode(outBytes)));
}
catch(Exception e)
{
System.out.println("Exception: " + e.toString());
}
}
}C#代码
using System;
using System.Collections.Generic;
using Org.BouncyCastle.Crypto.Paddings;
using System.Text;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Utilities.Encoders;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Crypto;
public class Decrypt
{
public string Decryption(string Request)
{
String EncryptedS = Request;
string convertHTML = string.Empty;
String key = ConfigurationSettings.AppSettings["EncDecKey"];//"123456789";
byte[] keyByte = Encoding.UTF8.GetBytes(key);
try
{
byte[] result = BouncyCastleCrypto(false, UrlBase64.Decode(EncryptedS), key);
convertHTML = Encoding.UTF8.GetString(result);
}
catch (Org.BouncyCastle.Crypto.CryptoException ex)
{
convertHTML = "false";
}
return convertHTML;
}
private byte[] BouncyCastleCrypto(bool forEncrypt, byte[] input, string key)
{
try
{
byte[] keyByte = Encoding.UTF8.GetBytes(key);
_PaddedBufferedBlockCipherWithlowfish.Init(forEncrypt, new KeyParameter(keyByte));
byte[] outBytes = new byte[_PaddedBufferedBlockCipherWithlowfish.GetOutputSize(input.Length)];
int len = _PaddedBufferedBlockCipherWithlowfish.ProcessBytes(input, 0, input.Length, outBytes, 0);
_PaddedBufferedBlockCipherWithlowfish.DoFinal(outBytes, len);
return outBytes;
}
catch (Org.BouncyCastle.Crypto.CryptoException ex)
{
throw new CryptoException(ex.ToString());
}
}
}注意:请确保两端使用相同的密钥。
https://stackoverflow.com/questions/2383322
复制相似问题