我正在尝试使用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(4.0支持BigInteger),我试图复制相同的行为。
我的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=
你知道我做错了什么,以及如何解决这个问题?
答案 0 :(得分:0)
@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
通过该更改,结果现在是正确的。现在我将看一下时间攻击问题:)