运行时错误 System.Security.Cryptography.CryptographicException:尝试导入 RSA 参数时 vb.net 中的 'Bad Data. '

RunTime Error System.Security.Cryptography.CryptographicException: 'Bad Data. ' in vb.net when trying to import RSA parameters

这是代码我不确定是否有任何隐藏的错误但是在运行时尝试导入 rsa 参数时它会弹出该错误

Function ModInverse(ByVal a As BigInteger, ByVal b As BigInteger) As BigInteger

    Dim b0 As BigInteger = b
    Dim t As BigInteger
    Dim q As BigInteger
    Dim x0 As BigInteger = 0
    Dim x1 As BigInteger = 1

    If b = 1 Then Return 1

    While a > 1
        q = BigInteger.Divide(a, b)
        t = b
        b = BigInteger.Remainder(a, b)
        a = t
        t = x0
        x0 = BigInteger.Subtract(x1, BigInteger.Multiply(q, x0))
        x1 = t
    End While

    If x1 < 0 Then x1 += b0
    Return x1

End Function
Private Sub GenerateBTN_Click(sender As Object, e As EventArgs) Handles GenerateBTN.Click

End Sub

Private Sub TestBTN_Click(sender As Object, e As EventArgs) Handles TestBTN.Click
    Dim MyRSACryptoServiceProvider As New RSACryptoServiceProvider(384)
    Dim MyRSAParams As RSAParameters
    Dim P As BigInteger
    Dim Q As BigInteger
    Dim Modulus As BigInteger
    Dim Modulus1 As BigInteger
    Dim Exponent As BigInteger
    Dim D As BigInteger
    Dim DP As BigInteger
    Dim DQ As BigInteger
    Dim InverseQ As BigInteger
    Dim PrimeList, PrimeList2 As New List(Of BigInteger)
    Dim x As Integer = 1
    Dim RandomNumber1, RandomNumber2 As Integer
    Dim Random As New Random
    Using StreamReader As New StreamReader("G:\PrimeList384P1.txt")
        Dim line As String
        While x <= 1000
            line = StreamReader.ReadLine
            If x >= 501 And x <= 1000 Then
                PrimeList2.Add(BigInteger.Parse(line))
            Else
                PrimeList.Add(BigInteger.Parse(line))
            End If
            x += 1
        End While
    End Using
    MessageBox.Show("PrimeList1 Count" & PrimeList.Count & vbNewLine & "PrimeList2 Count" & PrimeList2.Count)
    RandomNumber1 = Random.Next(0, (PrimeList.Count - 1))
    RandomNumber2 = RandomNumber1
    Q = PrimeList(RandomNumber1)
    P = PrimeList2(RandomNumber2)
    Modulus = (P - 1) * (Q - 1)
    Modulus1 = Modulus + 1
    D = BigInteger.Divide(Modulus1, 65537)
    x = 0
    If BigInteger.GreatestCommonDivisor(P, Q) = 1 And BigInteger.GreatestCommonDivisor(Modulus, 65537) = 1 And BigInteger.GreatestCommonDivisor(D, Modulus) = 1 Then
    Else
        While x < 500
            Q = PrimeList(x)
            P = PrimeList2(x)
            Modulus = (P - 1) * (Q - 1)
            Modulus1 = Modulus + 1
            If BigInteger.Remainder(Modulus1, 65537) = 0 Then
                D = BigInteger.Divide(Modulus1, 65537)
            End If
            If BigInteger.GreatestCommonDivisor(P, Q) = 1 And BigInteger.GreatestCommonDivisor(Modulus, 65537) = 1 And BigInteger.GreatestCommonDivisor(D, Modulus) = 1 Then
                Exit While
            End If
            x += 1
        End While
    End If
    Exponent = 65537
    ExponentTextBox.Text = Exponent.ToString
    DTextBox.Text = D.ToString
    PTextBox.Text = P.ToString
    QTextBox.Text = Q.ToString
    ModulusTextBox.Text = Modulus.ToString
    DP = BigInteger.Remainder(D, (P - 1))
    DQ = BigInteger.Remainder(D, (Q - 1))
    DPTextBox.Text = DP.ToString
    DQTextBox.Text = DQ.ToString
    MyRSAParams.P = P.ToByteArray
    MyRSAParams.Q = Q.ToByteArray
    MyRSAParams.Modulus = Modulus.ToByteArray
    MyRSAParams.Exponent = Exponent.ToByteArray
    MyRSAParams.D = D.ToByteArray
    MyRSAParams.DP = DP.ToByteArray
    MyRSAParams.DQ = DQ.ToByteArray
    InverseQ = ModInverse(Q, P)
    MyRSAParams.InverseQ = InverseQ.ToByteArray
    InverseQTextBox.Text = InverseQ.ToString
    MyRSACryptoServiceProvider.ImportParameters(MyRSAParams)
End Sub

Function RandomNumberGenerator(ByVal List As List(Of BigInteger)) As Integer
    Dim Random As New Random
    Dim RandomInteger As Integer
    RandomInteger = Random.Next(0, List.Count)
    Return RandomInteger
End Function

这是一些通过的(可能)RSA 密码术 (CRT) 数据:

P=153914086704665934422965000391185991426092731525255651046673021110334850669910978950836977558144201721900890764527

Q=153914086704665934422965000391185991426092731525255651046673021110334850669910978950836977558144201721900890636321

Modulus=23689546086131422960647270026588478931532074235789438036179382904450240366918592625898413220651954314430049636574759400990197139024354395962962505626040856607248107788273729363773001668779017561229086034747388110074639423184320

Exponent=65537

D=361468271146549627853689824474548406724935139475249676307725146168580196940943171428329237234721673473458498810973334162231977951757852754367189612372260808508905012256797371923844571292232136979554847410583153181784937107

DP=114907738137020230395758602608296812312065934785963783731504609257159521698848045807811642857696865920764862342291

DQ=108172220785463370912946395441018459268593789982044879796294602321467617099594117681241911993654301101831866315347

InverseQ=70202908196408513230673481177755980380197687014666822974402900452935518326945574435736969694613344805169792281463

我使用的是这些网站的参考资料

https://www.di-mgt.com.au/crt_rsa.html#PKCS1

https://www.c-sharpcorner.com/forums/modular-inverse-code

这是错误列表:

System.Security.Cryptography.CryptographicException
  HResult=0x80090005
  Message=Bad Data.
  Source=mscorlib
  StackTrace:
   at System.Security.Cryptography.CryptographicException.ThrowCryptographicException(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 RSATesting.Form1.TestBTN_Click(Object sender, EventArgs e) in C:\Users\chew\source\repos\RSATesting\Form1.vb:line 106
   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(IntPtr 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 Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun()
   at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel()
   at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(String[] commandLine)
   at RSATesting.My.MyApplication.Main(String[] Args) in :line 81

这是我尝试对主要功能进行一些更改的另一种尝试。

Private Sub TestBTN_Click(sender As Object, e As EventArgs) Handles TestBTN.Click
    Dim MyRSACryptoServiceProvider As New RSACryptoServiceProvider(384)
    Dim MyRSAParams As RSAParameters
    Dim P As BigInteger
    Dim Q As BigInteger
    Dim Modulus As BigInteger
    Dim Modulus1 As BigInteger
    Dim Exponent As BigInteger
    Dim D As BigInteger
    Dim DP As BigInteger
    Dim DQ As BigInteger
    Dim InverseQ As BigInteger
    Dim PrimeList, PrimeList2 As New List(Of BigInteger)
    Dim x As Integer = 1
    Dim RandomNumber1, RandomNumber2 As Integer
    Dim Random As New Random
    Using StreamReader As New StreamReader("G:\PrimeList384P1.txt")
        Dim line As String
        While x <= 1000
            line = StreamReader.ReadLine
            If x >= 501 And x <= 1000 Then
                PrimeList2.Add(BigInteger.Parse(line))
            Else
                PrimeList.Add(BigInteger.Parse(line))
            End If
            x += 1
        End While
    End Using
    RandomNumber1 = Random.Next(0, (PrimeList.Count - 1))
    RandomNumber2 = RandomNumber1
    Q = PrimeList(RandomNumber1)
    P = PrimeList2(RandomNumber2)
    Modulus = (P - 1) * (Q - 1)
    D = ModInverse(65537, Modulus)
    x = 0
    If BigInteger.GreatestCommonDivisor(P, Q) = 1 And BigInteger.GreatestCommonDivisor(Modulus, 65537) = 1 And BigInteger.GreatestCommonDivisor(D, Modulus) = 1 Then
    Else
        While x < 500
            Q = PrimeList(x)
            P = PrimeList2(x)
            Modulus = (P - 1) * (Q - 1)
            D = ModInverse(65537, Modulus)
            If BigInteger.GreatestCommonDivisor(P, Q) = 1 And BigInteger.GreatestCommonDivisor(Modulus, 65537) = 1 And BigInteger.GreatestCommonDivisor(D, Modulus) = 1 Then
                Exit While
            End If
            x += 1
        End While
    End If
    Exponent = 65537
    ExponentTextBox.Text = Exponent.ToString
    DTextBox.Text = D.ToString
    PTextBox.Text = P.ToString
    QTextBox.Text = Q.ToString
    ModulusTextBox.Text = Modulus.ToString
    DP = BigInteger.Remainder(D, (P - 1))
    DQ = BigInteger.Remainder(D, (Q - 1))
    InverseQ = ModInverse(Q, P)
    DPTextBox.Text = DP.ToString
    DQTextBox.Text = DQ.ToString
    InverseQTextBox.Text = InverseQ.ToString
    MyRSAParams.P = ExportUnsignedBigEndian(P)
    MyRSAParams.Q = ExportUnsignedBigEndian(Q)
    MyRSAParams.Modulus = ExportUnsignedBigEndian(Modulus)
    MyRSAParams.Exponent = ExportUnsignedBigEndian(Exponent)
    MyRSAParams.D = ExportUnsignedBigEndian(D)
    MyRSAParams.DP = ExportUnsignedBigEndian(DP)
    MyRSAParams.DQ = ExportUnsignedBigEndian(DQ)
    MyRSAParams.InverseQ = ExportUnsignedBigEndian(InverseQ)
    MyRSACryptoServiceProvider.ImportParameters(MyRSAParams)
End Sub

System.Security.Cryptography.CryptographicException HResult=0x80090005

消息=错误数据。

来源=mscorlib 堆栈跟踪:

在 System.Security.Cryptography.CryptographicException.ThrowCryptographicException(Int32 小时)

在 System.Security.Cryptography.Utils._ImportKey(SafeProvHandle hCSP、Int32 keyNumber、CspProviderFlags 标志、对象 cspObject、SafeKeyHandle& hKey)

在System.Security.Cryptography.RSACryptoServiceProvider.ImportParameters(RSAParameters 参数)

at RSATesting.Form1.TestBTN_Click(Object sender, EventArgs e) in C:\Users\chew\source\repos\RSATesting\Form1.vb:line 109

在System.Windows.Forms.Control.OnClick(EventArgs e) 在 System.Windows.Forms.Button.OnClick(EventArgs e)

at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent) 在 System.Windows.Forms.Control.WmMouseUp(消息& m,MouseButtons 按钮,Int32 点击)

在System.Windows.Forms.Control.WndProc(留言&米) 在 System.Windows.Forms.ButtonBase.WndProc(消息& m)

在System.Windows.Forms.Button.WndProc(留言&米) 在 System.Windows.Forms.Control.ControlNativeWindow.OnMessage(消息& m)

在System.Windows.Forms.Control.ControlNativeWindow.WndProc(留言&米) 在 System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

在 System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(消息&消息) 在

System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 原因, Int32

pvLoopData) 在 System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 原因,

ApplicationContext上下文) 在 System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 原因,

ApplicationContext上下文) 在 Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun() 在

Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel() 在 Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(字符串[] 命令行)

在 RSATesting.My.MyApplication.Main(String[] Args) 中:第 81 行

MyRSAParams.P = P.ToByteArray

BigInteger 的 ToByteArray 生成一个带符号的小端值。数字 65532 (0xFFFC) 生成字节数组 new byte[] { 0xFC, 0xFF, 0x00 }.

RSAParameters 值是 unsigned,big-endian 值。因此,相同的字节数组(我们打算将其设为 0xFFFC)被解释为 0xFCFF00 (16,580,352)。

要将有符号的小端转换为无符号的大端,您需要删除最后一个字节(如果它为零),然后反转。

我不能可靠地编写 VB,所以这里有一些 C#:

private static byte[] ExportUnsignedBigEndian(BigInteger val)
{
    byte[] export = val.ToByteArray();

    if (export[export.Length - 1] == 0)
    {
        Array.Resize(ref export, export.Length - 1);
    }

    Array.Reverse(export);
    return export;
}

或者,如果您正在构建 netcoreapp2.1 或更高版本,或者 netstandard2.1 或更高版本:

val.ToByteArray(isUnsigned: true, isBigEndian: true);