与.NET RSACryptoServiceProvider.SignData相当的Java版本

与.NET RSACryptoServiceProvider.SignData相当的Java版本,java,c#,encryption,rsa,digital-signature,Java,C#,Encryption,Rsa,Digital Signature,我目前正在通过使用公钥加密数据,然后使用rsacryptserviceprovider.SignData方法对其进行签名来创建签名哈希 String data = "some string here"; // **Step 1: encrypt data with public key** Byte[] encryptedData = publicKeyRsa.Encrypt(System.Text.Encoding.UTF8.GetBytes(data), false); // **Step

我目前正在通过使用公钥加密数据,然后使用rsacryptserviceprovider.SignData方法对其进行签名来创建签名哈希

String data = "some string here";
// **Step 1: encrypt data with public key**
Byte[] encryptedData = publicKeyRsa.Encrypt(System.Text.Encoding.UTF8.GetBytes(data), false);

// **Step 2: sign the encrypted data with private key**
Byte[] sign = privateKeyRsa.SignData(encryptedData, new SHA1CryptoServiceProvider());

// **Step 3: get hash for sign**
String signHash = System.Web.HttpServerUtility.UrlTokenEncode(sign);
我无法在Java中成功实现相同的算法。 这就是我现在拥有的

    Base64 base64Encoder = new Base64();

    // initialize cipher to encrypt
    Cipher cipher = Cipher.getInstance("RSA");
    cipher.init(Cipher.ENCRYPT_MODE, pubKey);

    // **Step 1: encrypt data with public key**
    byte[] encBytes = cipher.doFinal(VALUE.getBytes("UTF-8"));
    byte[] encryptedData  = base64Encoder.encode(encBytes);
    String encryptedDataString = bytes2String(encryptedData);
    System.out.println("data encrypted: " + encryptedData);

    // **Step 2: sign the encrypted data with private key**
    Signature sig = Signature.getInstance("SHA1WithRSA");
    sig.initSign(privKey);
    sig.update(encryptedData);
    byte[] signData = sig.sign();

    // **Step 3: get hash for sign**
    byte[] signDataEncrypted = base64Encoder.encode(signData);
    String signDataString = bytes2String(signDataEncrypted);
    System.out.println("hash: "+signDataString);
我对Bytes2字符串的实现就是从这里开始的

C#代码工作得很好,但java代码没有提供“正确的值”(根据服务器)。Java代码看起来正确吗?与C代码相比,我有没有做错什么


谢谢

我终于成功地解决了这个问题谢谢你们的帮助

以下是修复程序

问题1:密码算法不正确 我将密码算法从
“RSA”
更改为
“RSA/ECB/pkcs1p添加”

问题2:
bytes2字符串()
方法 我用这个替换了我的
bytesString()
逻辑

public String bytes2String(byte[] bytes) {
  return Base64.encodeBase64URLSafeString(bytes);
}
问题3:C#URLTokencode方法 我假设用于转换为字符串的Java和C方法是相同的。 实际上,C#添加了额外的填充字符,如本文所述()


希望这对某人有帮助

这可能是RSA算法的实现不匹配。请在C#中编辑并添加RSA对象创建代码。另外,您是否完全确定在两台加密机中使用相同的密钥?密钥来自哪里?如果我没记错的话,您必须从rsa指数和模中删除第一个字节,以实现JAVAc#可比性。您是否已经在
encryptedDataString
中看到不匹配,或者仅在哈希中看到不匹配?@jHilscher,对于相同的值(在.NET和Java实现中),哈希和加密数据每次都不同,所以没有办法证实这一点。与.NET版本的代码相比,您是否怀疑Java方面有什么做错了?再看一看,如果没有base64编码调用(我在您的c#代码中没有看到相应的操作),我会这么说加密操作看起来还可以-确保我也会在密码中显式使用块链接模式和填充,但您不必选择BouncyCastle提供程序。
public String bytes2String(byte[] bytes) {
  return Base64.encodeBase64URLSafeString(bytes);
}