0

I am trying to send a third party an RSA encrypted string. They have provided me with a public key. I have multiple systems that need to transmit the data.

One such system is vb.net/asp.net, and is using javascript to do the encryption which works perfectly, via jsencrypt: https://unpkg.com/browse/jsencrypt@2.3.1/README.md The result is consistently 344 characters and ends with =

I also have a desktop app in vb.net that needs to do the same, so I'm using System.Security.Cryptography.RSACryptoServiceProvider, but the result is much longer than what I see sending via the JS code. (It also doesn't end with "=" like the JS code) The result is consistently 392 and never ends with =

Here is my vb.net code:

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    Dim strPublicKey As String = "<RSAKeyValue><Modulus>[Redacted]</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>"
    Dim fStringToSend As String = "This is a test."
    Dim byStringToSend As Byte() = Encoding.UTF8.GetBytes(fStringToSend)
Dim RSA As System.Security.Cryptography.RSACryptoServiceProvider = New System.Security.Cryptography.RSACryptoServiceProvider(1024)
    RSA.FromXmlString(strPublicKey)
    Dim strEncryptedStringToSend As String = Convert.ToBase64String(RSA.Encrypt(byStringToSend, True))
TextBox1.Text = strEncryptedStringToSend
End Sub

What am I missing? Let me know if any further data is needed to diagnose & thanks!

EDIT (adding full code, with a key I generated myself to test with)

EncTest.aspx

<%@ Page Language="VB" AutoEventWireup="false" CodeFile="EncTest.aspx.vb" Inherits="EncTest" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <script type="text/javascript" src="jsencrypt.js"></script>
    <script type="text/javascript">
        const publicKey = 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC0qoqRSNKH+sq7mZKm9f822bhqtD4y4DIRD8++9d0zok5FQrjZHSuGc917zzUGd2IiUzRrLOt/ZMenk42/Wm55rkYf9/MsdHo94vqcHj/5yFYg3QUhgN7l7okIRfAzCkxMl/6x4RymVInB1td5F6N2mChqRm+hzWr9d0I4wLWOpwIDAQAB';

        function encText() {
            var textToEncrypt = 'This is a test.';
            const crypt = new JSEncrypt();
            crypt.setKey(publicKey);
            const encryptedText = crypt.encrypt(textToEncrypt);
            document.getElementById('Label2').innerHTML = encryptedText;
        }
    </script>
</head>
<body>
    <form id="form1" runat="server">
        <div>
            <asp:Button ID="Button1" runat="server" Text="net" /><br />
            <br />
            <asp:label ID="Label1" runat="server"></asp:label><br />
            <br />
            <div id="Label2"></div><br />
            <br />
            <div onclick="encText();">js</div>
        </div>
    </form>
</body>
</html>

EncTest.aspx.vb

Partial Class EncTest
    Inherits System.Web.UI.Page

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim strPublicKey As String = "<RSAKeyValue><Modulus>MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC0qoqRSNKH+sq7mZKm9f822bhqtD4y4DIRD8++9d0zok5FQrjZHSuGc917zzUGd2IiUzRrLOt/ZMenk42/Wm55rkYf9/MsdHo94vqcHj/5yFYg3QUhgN7l7okIRfAzCkxMl/6x4RymVInB1td5F6N2mChqRm+hzWr9d0I4wLWOpwIDAQAB</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>"
        Dim fStringToSend As String = "This is a test."
        Dim byStringToSend As Byte() = Encoding.UTF8.GetBytes(fStringToSend)
        Dim RSA As System.Security.Cryptography.RSACryptoServiceProvider = New System.Security.Cryptography.RSACryptoServiceProvider(1024)
        RSA.FromXmlString(strPublicKey)
        Dim strEncryptedStringToSend As String = Convert.ToBase64String(RSA.Encrypt(byStringToSend, False))
        Label1.Text = strEncryptedStringToSend
    End Sub
End Class

And here are examples of the encrypted strings: .net: JNG3rMmqZkzWXwIIOLVCa2e3vTV2doPEKiSyxBFtgYEbnKpkkCKiri7Vdkovn+2T+ArPuVzgTpPEelWN/3gBtvTxSQ4Vt1+H4MMUjFcCwkYoom1V2FyzIBIZ0eqjNQfqos9F10FIQ3NkqiDCDoNHKA5yNfPLBeNQfB5C/bCzCffE6hgHqc7+zkc651V9WSBTuZq7KzgHFUmYHB+juLuZxZGt

javascript: UGjvEQy5ZFSDJt/SKL/39giZP7iYqlR3u3f6P5FpCf/z5p/lnIIyhSNNoSOwKQspPajbczO9DxSFElKKmQSEH9keQrhj4DtcSyPMHInFWra13/fWK9VA5XiktEc2vb9XUQVeZ7DS19ZDYVq7cpA9vApiYztSMClS8CCMuatO0Gs=

msimmons
  • 146
  • 1
  • 3
  • 15
  • _JSEncrypt_ supports only _PKCS#1 v1.5_ padding. But in the VB code _OAEP_ is used, because the 2nd parameter in `Encrypt()` is `True`. Set it to `False` for _PKCS# 1 v1.5_. But this does not explain the different lengths (at least when the same key is used). In both cases the ciphertext has the length of the key (e.g. for a 2048 bit key, 256 bytes or 344 bytes Base64 encoded). You should post a concrete example (test key, plaintext, ciphertext). – Topaco Jan 18 '21 at 20:43
  • @Topaco - I changed that parameter and see no change in the result (that I can tell). I've updated my post to include the full code (it's just a quick & dirty page I threw together). – msimmons Jan 18 '21 at 21:54
  • Which .NET version are you using? – Topaco Jan 18 '21 at 22:03
  • The public key used in the _JSEncrypt_ code has the _X.509/SPKI_ format and is PEM encoded (without header and footer). In the VB code you use this key as modulus, which is wrong (the modulus is only a part of the key). Starting with _.NET Core 3.0_ (but not in _.NET Framework_) you can import this key directly with `RSA.ImportSubjectPublicKeyInfo()` (after Base64 decoding). – Topaco Jan 18 '21 at 22:29
  • @Topaco - it's framework, 4.5. – msimmons Jan 18 '21 at 22:32
  • OK, for the .NET Framework another option is a key conversion from the PEM to the XML format, e.g. here https://superdry.apphb.com/tools/online-rsa-key-converter, in the field _PEM to XML_. For this, you have to add header (`-----BEGIN PUBLIC KEY-----`) and footer (`-----END PUBLIC KEY-----`) in your key. Then use this XML key in the VB code for `strPublicKey`. – Topaco Jan 18 '21 at 22:35
  • @Topaco - That appears to have done it!! I haven't tried in the live application, but my test results are the same length and have the "=" at the end. Thank you so much!! – msimmons Jan 18 '21 at 22:40

1 Answers1

0

To achieve interoperability with .NET I managed to give a twist to JSEncrypt and fix paddings. I also added PrivateKey encryption for JS possibility.

You can read here Decrypting RSA with JavaScript someone that used my version of JSEncrypt.

Michaelsoft
  • 777
  • 5
  • 18