C# 等效的 Java 加密代码。

huangapple go评论147阅读模式
英文:

java cipher to c# equivalent

问题

以下是您提供的内容的翻译部分:

原始 Java 代码段:

try {
  cipher = Cipher.getInstance("RSA/None/PKCS1Padding", "SC");
} catch (SecurityException se) {
  // workaround for tests
  Log.i("Moip SDK", "No SC provider, running test profile");
  cipher = Cipher.getInstance("RSA");
}

BufferedReader pemReader = null;
pemReader = new BufferedReader(new InputStreamReader(
  new ByteArrayInputStream(publicKey.getBytes("UTF-8"))));

StringBuffer content = new StringBuffer();
String line = null;
while ((line = pemReader.readLine()) != null) {
  if (line.indexOf("-----BEGIN PUBLIC KEY-----") != -1) {
    while ((line = pemReader.readLine()) != null) {
      if (line.indexOf("-----END PUBLIC KEY") != -1) {
        break;
      }
      content.append(line.trim());
    }
    break;
  }
}
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, keyFactory.generatePublic(new X509EncodedKeySpec(Base64.decode(content.toString(), Base64.DEFAULT))));
byte[] cipherText = cipher.doFinal(toHash().getBytes());

return Base64.encodeToString(cipherText, Base64.DEFAULT);

您创建的类似代码段,用于在 C# 中实现相同的功能:

private string Payload(string number, string expirationMonth, string expirationYear, string cvc) {
  return string.Join("&",
    new List<string> {
      $"number={number}",
      $"cvc={cvc}",
      $"expirationMonth={expirationMonth}",
      $"expirationYear={expirationYear}",
    }
  );
}

private string Encrypt(string key, string payload) {
  var publicKey = $"<RSAKeyValue><Modulus>{key}</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>";
  var rsa = new RSACryptoServiceProvider(2048);
  rsa.FromXmlString(publicKey);
  var encryptedData = rsa.Encrypt(Encoding.UTF8.GetBytes(payload), RSAEncryptionPadding.Pkcs1);
  rsa.Dispose();

  return Convert.ToBase64String(encryptedData);
}

var payload = Payload(number, expirationMonth, expirationYear, cvc);
hash = Encrypt(ClientManager.Environment.publicKeyCreditCard, payload);

请注意,为了保持代码的一致性,我已将注释和不相关的细节从翻译中删除。

英文:

I am very grateful with any help. I am trying to convert a rsa cryptor java implementation to c#. I need to encrypt credit card data. The platform i use provides cryptography SDK for javascript and android, but I need a C# implementation.

    try {
      cipher = Cipher.getInstance(&quot;RSA/None/PKCS1Padding&quot;, &quot;SC&quot;);
    } catch (SecurityException se) {
      //workaround for tests
      Log.i(&quot;Moip SDK&quot;, &quot;No SC provider, running test profile&quot;);
      cipher = Cipher.getInstance(&quot;RSA&quot;);
    }

    BufferedReader pemReader = null;
    pemReader = new BufferedReader(new InputStreamReader(
      new ByteArrayInputStream(publicKey.getBytes(&quot;UTF-8&quot;))));

    StringBuffer content = new StringBuffer();
    String line = null;
    while ((line = pemReader.readLine()) != null) {
      if (line.indexOf(&quot;-----BEGIN PUBLIC KEY-----&quot;) != -1) {
        while ((line = pemReader.readLine()) != null) {
          if (line.indexOf(&quot;-----END PUBLIC KEY&quot;) != -1) {
            break;
          }
          content.append(line.trim());
        }
        break;
      }
    }
    KeyFactory keyFactory = KeyFactory.getInstance(&quot;RSA&quot;);
    cipher.init(Cipher.ENCRYPT_MODE, keyFactory.generatePublic(new X509EncodedKeySpec(Base64.decode(content.toString(), Base64.DEFAULT))));
    byte[] cipherText = cipher.doFinal(toHash().getBytes());

    return Base64.encodeToString(cipherText, Base64.DEFAULT);

The code I created looking at the implementation in java, it works but fails to be decrypted on the platform, I must be forgetting something. My implementation:

  private string Payload(string number, string expirationMonth, string expirationYear, string cvc) {
    return String.Join(
      &quot;&amp;&quot;,
      new List&lt;string&gt; {
        $&quot;number={number}&quot;,
        $&quot;cvc={cvc}&quot;,
        $&quot;expirationMonth={expirationMonth}&quot;,
        $&quot;expirationYear={expirationYear}&quot;,
      }
    );
  }

  private string Encrypt(string key, string payload) {
    var publicKey = $&quot;&lt;RSAKeyValue&gt;&lt;Modulus&gt;{key}&lt;/Modulus&gt;&lt;Exponent&gt;AQAB&lt;/Exponent&gt;&lt;/RSAKeyValue&gt;&quot;;
    var rsa = new RSACryptoServiceProvider(2048);
    rsa.FromXmlString(publicKey);
    var encryptedData = rsa.Encrypt(Encoding.UTF8.GetBytes(payload), RSAEncryptionPadding.Pkcs1);
    rsa.Dispose();

    return Convert.ToBase64String(encryptedData);
  }


var payload = Payload(number, expirationMonth, expirationYear, cvc);
hash = Encrypt(ClientManager.Environment.publicKeyCreditCard, payload);

答案1

得分: 0

欢迎来到Stack Overflow。我运行了你的代码,在Java和C#两个平台上都成功地进行了加密和解密。

因此在我看来,当在C#上进行加密时解密失败的唯一原因是你没有正确地转换公钥。

我建议使用一个在线转换工具,比如https://superdry.apphb.com/tools/online-rsa-key-converter (因为这是公钥)。只需要将公钥复制到下方的输入文本区域“PEM to XML”中,就像这个(这是一个不安全的 512 位RSA密钥,所以会比你的密钥更短):

-----BEGIN PUBLIC KEY-----
MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJn4LYaoLyuT+pD9NKI8wOvPrRjMIxGn
HbqIxUrpGsyj162fEOV4836oCZg0N8HFnt4Vivdjt8/7ZgLjeOygNGUCAwEAAQ==
-----END PUBLIC KEY-----

然后点击“Convert”按钮 - 在下面你会得到公钥的xml格式:

&lt;RSAKeyValue&gt;&lt;Modulus&gt;mfgthqgvK5P6kP00ojzA68+tGMwjEacduojFSukazKPXrZ8Q5XjzfqgJmDQ3wcWe3hWK92O3z/tmAuN47KA0ZQ==&lt;/Modulus&gt;&lt;Exponent&gt;AQAB&lt;/Exponent&gt;&lt;/RSAKeyValue&gt;

你需要注意<Exponent>的值 - 大多数情况下是“AQAB”,但如果你收到其他值,就必须在C#中调整你的源代码。

英文:

Welcome to Stackoverflow. I run your codes and I could encrypt and decrypt on both platforms (Java & C#) successfully.

So in my eyes the only reason why decryption fails when doing encryption on C# is that you didn't convert the public key correctly.

I recommend to use (as it is the pub key) an online converter like https://superdry.apphb.com/tools/online-rsa-key-converter.

Just copy the public key in the lower input text area "PEM to XML" like this one (it's an unsecure 512 bit RSA-key so it will be shorter than your one):

-----BEGIN PUBLIC KEY-----&quot; +
MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJn4LYaoLyuT+pD9NKI8wOvPrRjMIxGn
HbqIxUrpGsyj162fEOV4836oCZg0N8HFnt4Vivdjt8/7ZgLjeOygNGUCAwEAAQ==
-----END PUBLIC KEY-----

and press "Convert" - below you get the public key in xml-format:

&lt;RSAKeyValue&gt;&lt;Modulus&gt;mfgthqgvK5P6kP00ojzA68+tGMwjEacduojFSukazKPXrZ8Q5XjzfqgJmDQ3wcWe3hWK92O3z/tmAuN47KA0ZQ==&lt;/Modulus&gt;&lt;Exponent&gt;AQAB&lt;/Exponent&gt;&lt;/RSAKeyValue&gt;

The partial key that you have to present to your C# method is after Modulus:

mfgthqgvK5P6kP00ojzA68+tGMwjEacduojFSukazKPXrZ8Q5XjzfqgJmDQ3wcWe3hWK92O3z/tmAuN47KA0ZQ==

You should have an eye on the <Exponent> value - in most times it is "AQAB" but in case you receive another value you have to adjust your source code in C#.

huangapple
  • 本文由 发表于 2020年8月23日 20:56:08
  • 转载请务必保留本文链接:https://go.coder-hub.com/63547220.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定