Perl 和.NET RSA 一起工作吗?从 Perl 公钥在 .NET 中加密?从 Perl 加载私钥?
我有一个应用程序将从第三方获取公钥。公钥是在 Perl 中使用 Crypt::RSA::Key 生成的。使用 BigInteger 类,我可以加载此密钥并加密以下值:应该可以用私钥解密。我的代码是:
设置属性以供以后使用:
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 ... //
初始化构造函数中的属性:
RSAParameters rsaParameters = new RSAParameters();
rsaParameters.Exponent = this.Exponent.getBytes();
rsaParameters.Modulus = this.Modulus.getBytes();
this.RsaParams = rsaParameters;
// 。 .. snip ... //
进行加密。注意 text 是我要加密的值; ret 是我返回的值:
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);
这段代码的大部分是从其他人的项目中提取的,他们声称这一切都适合他们。不幸的是,我无法看到他们的实际输入值。
由于返回给第 3 方的无效值,此操作失败。
第一个问题 - 您发现上面的代码有什么问题吗?
其次
我尝试通过与第 3 方交谈并从他们那里获取私钥来调试此问题。当我尝试加载完整的私钥时,我失败了。我无法弄清楚 Perl 的对象数据和 .NET RSAParameters 之间的映射。我拥有的关键数据是:
$VAR1 = bless( {
'Version' => '1.91', '已检查' => 0, '身份' => “给我的东西(2048)”, '私人' => { '_phi'=> '218..剪断..380', '_n'=> '218..剪断..113', '_q'=> '148..剪断..391', '_p'=> '146..剪断..343', '_u'=> '127..剪断..655', '_dp'=> '127..剪..093', '_dq'=> '119..剪断..413', '_d'=> '190..剪断..533', '_e'=> ‘65537’ }, '密码' => “河豚” }, 'Crypt::RSA::Key::Private');
我发现到 RSAParameters 对象的映射是这样的:
_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
当我加载这些值时(全部以与上面相同的方式使用 BigInteger 类);我因“数据错误”而失败。当我尝试调用时出错: rsa.ImportParameters(this.RsaParams);
此错误的堆栈跟踪是:
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()
对问题的这一部分有什么想法吗?
最后,我主要是一名 VB.NET 开发人员,但在涉及 C# 时,我感觉双向摇摆好像我对此相当流利一样。然而,在加密方面,我是个新手。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
查看如何使用MSDN 论坛中的 RSACryptoServiceProvider.ImportParameters() 主题。它解决了您在这里询问的同一问题。 getBytes 可能正在修改您的公钥数据。 Voss 在该线程中发布的消息之一包括针对 BigInteger 类的 getBytes 问题的修复。
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.