开发者

Perl & .NET RSA working together? Encrypting in .NET from Perl public key? Loading private key from Perl?

I've got an application that is going to be taking a public key from a 3rd party. The public key is generated in Perl using Crypt::RSA::Key. Using the BigInteger class, I'm able to load this key and encrypt values that should be able to be decrypted by the private key. My code for doing that is:

Setting up the properties for later usage:

internal RSAParameters RsaParams
{
    get { return this._rsaParams; }
    set { this._rsaParams = value; }
}

public BigInteger Modulus
{
    get { return new BigInteger(this._modulus, 10); }
}

public BigInteger Exponent
{
    get { return new BigInteger(this._exponent, 10); }
}

// ... snip ... //

Initializing the properties in a constructor:

    RSAParameters rsaParameters = new RSAParameters();
    rsaParameters.Exponent = this.Exponent.getBytes();
    rsaParameters.Modulus = this.Modulus.getBytes();
    this.RsaParams = rsaParameters;

// ... snip ... //

Doing the encryption. Note text is my value to encrypt; ret is my value being returned:

RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();

rsa.ImportParameters(this.RsaParams);

Byte[] toEncode = encoding.GetBytes(text);
Byte[] encryptedVal = rsa.Encrypt(toEncode, true);

ret = Convert.ToBase64String(encryptedVal);

The majority of this code was pulled from someone else's project who claims this all works for them. Unfortunately, I'm not able to see their actual input values.

This is failing with an invalid value being returned to the 3rd party.

FIRST QUESTION - do you see anything amiss about the code above?

SECONDLY

I tried debugging this by talking to the 3rd party and getting a private key from them. I'm failing when I try to load the full private key. I can't figure out the mapping between the Perl's object data and .NET RSAParameters. The key data that I have is:

$VAR1 = bless( {

'Version' => '1.91', 'Checked' => 0, 'Identity' => 'stuff for me (2048)', 'private' => { '_phi' => '218..snip..380', '_n' => '218..snip..113', '_q' => '148..snip..391', '_p' => '146..snip..343', '_u' => '127..snip..655', '_dp' => '127..snip..093', '_dq' => '119..snip..413', '_d' => '190..snip..533', '_e' => '65537' }, 'Cipher' => 'Blowfish' }, 'Crypt::RSA::Key::Private' );

I have figured out that the mapping to the RSAParameters objects is as such:

    _phi = ???
    _n = RSAParameters.Modulus
    _q = RSAParameters.Q
    _p = RSAParameters.P
    _u = ???
    _dp = RSAParameters.DP
    _dq = RSAParameters.DQ
    _d = RSAParameters.D    
    _e = RSAParameters.Exponent
    ??? = RSAParamaters.InverseQ

When I load these values (all using the BigInteger class in the same manner as above); I fail with a "Bad data." error when I attempt to call: rsa.ImportParameters(this.RsaParams);

The stack trace of this error is:

System.Security.Cryptography.CryptographicException was unhandled
  Message="Bad Data.\r\n"
  Source="mscorlib"
  StackTrace:
       at System.Security.Cryptography.CryptographicException.ThrowCryptogaphicException(Int32 hr)
       at System.Security.Cryptography.Utils._ImportKey(SafeProvHandle hCSP, Int32 keyNumber, CspProviderFlags flags, Object cspObject, SafeKeyHandle& hKey)
       at System.Security.Cryptography.RSACryptoServiceProvider.ImportParameters(RSAParameters parameters)
       at SandboxApp2.SandboxDecrypter.DecryptText(String text) in C:\Doug\Development\SandboxApp2\SandboxApp2\SandboxDecrypter.cs:line 101
       at SandboxApp2.Form1.btnGoDecrypter_Click(Object sender, EventArgs e) in C:\Doug\Development\SandboxApp2\SandboxApp2\Form1.cs:line 165
       at System.Windows.Forms.Control.OnClick(EventArgs e)
       at System.Windows.Forms.Button.OnClick(EventArgs e)
       at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
       at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
       at System.Windows.Forms.Control.WndProc(Message& m)
       at System.Windows.Forms.ButtonBase.WndProc(Message& m)
       at System.Windows.Forms.Button.WndProc(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
       at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
       at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
       at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.Run(Form mainForm)
       at SandboxApp2.Program.Main() in C:\Doug\Development\SandboxApp2\SandboxApp2\Program.cs:line 17
       at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
       at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
开发者_开发问答

Any ideas for this portion of the question?

Finally, I'm primarily a VB.NET developer but swing both ways when it comes to c# and I feel like I'm fairly fluent in it. I am, however, a neophyte when it comes to encryption.


Check out the How to use RSACryptoServiceProvider.ImportParameters() thread in the MSDN forums. It addresses the same problem you are asking about here. It might be possible that getBytes is munging your public key data. One of the messages posted by Voss in the thread includes a fix to the BigInteger class for an issue with getBytes.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜