【问题标题】:Decrypt a mesage using RSA in .NET - m**d mod p*q not working在 .NET 中使用 RSA 解密消息 - m**d mod p*q 不起作用
【发布时间】:2013-02-07 16:32:02
【问题描述】:

我正在尝试使用 Mega 加密 API,但我被 RSA 解密部分卡住了。

使用的 JavaScript 是这样的:

// Compute m**d mod p*q for RSA private key operations.

function RSAdecrypt(m, d, p, q, u)
{    
 var xp = bmodexp(bmod(m,p), bmod(d,bsub(p,[1])), p);
 var xq = bmodexp(bmod(m,q), bmod(d,bsub(q,[1])), q);

 var t=bsub(xq,xp);
 if(t.length==0)
 {
  t=bsub(xp,xq);
  t=bmod(bmul(t, u), q);
  t=bsub(q,t);
 }
 else
 {
  t=bmod(bmul(t, u), q);
 } 
 return badd(bmul(t,p), xp);
}

我正在使用 .NET(支持 BigInteger 的 4.0)并且我正在尝试复制相同的行为。

我拥有的 RSA 数据是:

p (1024 bits)
q (1024 bits)
d (2044 bits)
u (1024 bits)
m (2044 bits) (the ciphered data)

我尝试使用 RSACryptoServiceProvider,但没有成功。 在另一个post 中,另一位用户报告说他使用基本的 RSA 解密算法 (m**d mod p*q) 并避免使用 RSACryptoServiceProvider。

我实现了它(U 部分不是必需的,我理解),确保输入与 Javascript 输入完全相同,但仍然没有运气。输出与 Javascript 代码预期的不同。

这是实现的功能:

Public Shared Function RSA_Decrypt(ByVal P As Numerics.BigInteger, ByVal Q As Numerics.BigInteger, ByVal D As Numerics.BigInteger, ByVal M As Numerics.BigInteger) As Byte()
    Dim N As System.Numerics.BigInteger = Numerics.BigInteger.Multiply(P, Q)
    Dim DecryptedData As System.Numerics.BigInteger = Numerics.BigInteger.ModPow(M, D, N)
    Return DecryptedData.ToByteArray
End Function

测试代码:

Dim P As New Numerics.BigInteger(Convert.FromBase64String("gbb1FjTy...s="))
Dim Q As New Numerics.BigInteger(Convert.FromBase64String("o0fGo0v...8="))
Dim D As New Numerics.BigInteger(Convert.FromBase64String("GFVe9C...bQ=="))
Dim Data As New Numerics.BigInteger(Convert.FromBase64String("BnrSc/..Dg=="))

Dim ResultBytes As Byte() = cripto.RSA_Decrypt(P, Q, D, Data)
Dim ResultStr As String = Convert.ToBase64String(ResultBytes)

此代码返回:

Vd2jBCzObTx...QW1y+VRSZHAw==

但是,JavaScript 函数返回

LUyj3pyIyr4g...1aZU=

您知道我做错了什么,以及如何解决这个问题吗?

【问题讨论】:

  • 可能是字节序问题。猜猜你的 .net 代码使用的是小端,而 js 使用的是大端。
  • 并使用ModPow 尖叫“定时攻击”。
  • 感谢cmets,没听说过“定时攻击”,待查。。。关于big endian和little endian,我测试过:Convert.FromBase64String("...").Reverse.ToArray 结果还是错:(
  • SJCL 没有 RSA 实现。

标签: vb.net encryption cryptography rsa rsacryptoserviceprovider


【解决方案1】:

@CodesInChaos 是对的,这是字节序问题。

我使用了取自here 的函数“OS2IP”。只是用它从字节数组中生成 BigInteger。

Dim P As Numerics.BigInteger = cripto.OS2IP(Convert.FromBase64String("gbb1FjTyN ... hs="), false)

然后我不得不反转生成的字节数组:

Dim ResultBytes As Byte() = cripto.RSA_Decrypt(P, Q, D, Data).Reverse.ToArray

以及纠正字节顺序的函数:

''' <summary>
''' Converts a byte array to a non-negative integer.
''' </summary>
''' <param name="data">The number in the form of a byte array.</param>
''' <param name="isLittleEndian">Endianness of the byte array.</param>
''' <returns>An non-negative integer from the byte array of the specified endianness.</returns>
Public Shared Function OS2IP(data As Byte(), isLittleEndian As Boolean) As Numerics.BigInteger
    Dim bi As Numerics.BigInteger = 0
    If isLittleEndian Then
        For i As Integer = 0 To data.Length - 1
            bi += Numerics.BigInteger.Pow(256, i) * data(i)
        Next
    Else
        For i As Integer = 1 To data.Length
            bi += Numerics.BigInteger.Pow(256, i - 1) * data(data.Length - i)
        Next
    End If
    Return bi
End Function

有了这个改变,结果现在是正确的。现在我来看看时间攻击问题:)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-08-07
    • 1970-01-01
    • 2021-07-31
    • 2014-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多