首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在C# .NET中与Java代码一样进行加密

如何在C# .NET中与Java代码一样进行加密
EN

Stack Overflow用户
提问于 2010-03-05 06:49:04
回答 2查看 8.3K关注 0票数 2

我需要将私钥中的加密字符串发送到key服务器进行身份验证。我有正确生成加密字符串的Java客户端代码(这样key服务器就可以用公钥解密它)。我正在尝试编写C#代码来执行完全相同的加密-但没有成功。

首先,在java中使用keytool生成一个密钥库,如下所示:

代码语言:javascript
复制
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"):

代码语言:javascript
复制
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证书:

代码语言:javascript
复制
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#代码应该可以工作:

代码语言:javascript
复制
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客户端。

我是不是遗漏了一些标志,设置,变量,什么?

EN

回答 2

Stack Overflow用户

发布于 2010-03-05 06:55:47

您确定与java实现相比,加密算法块密码模式填充模式在C#实现中是等效的吗?

编辑:实际上,对于RSACryptoProvider,您可能不需要密码/填充模式-看看MSDN上的示例,特别是关于通过ImportParameters导入公钥信息的部分

票数 2
EN

Stack Overflow用户

发布于 2011-06-04 00:26:41

这是一个在工作条件下很难找到的解决方案,在Java中加密,在.Net中解密,最终我能够在我的一个项目中实现,使用它我们可以在java中加密任何字符串,并在.Net端使用BouncyCastle API解密。

我已经使用Blowfish进行了加密/解密:

你可以从以下网址查阅bouncycastle的文件:http://bouncycastle.org/latest_releases.html

Java代码

代码语言:javascript
复制
  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#代码

代码语言:javascript
复制
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());
}
}     
}

注意:请确保两端使用相同的密钥。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2383322

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档