问题
I'm using someone else's code to generate an RSA signature used for verification in xbox 360 save files. The code reads the needed values from a files and correctly generates the signature.
The code is:
byte[] xHash=null;
RSAParameters xParams = new RSAParameters();
br.BaseStream.Position = 0x1A8;
xParams.D = br.ReadBytes(0x80);
xParams.Exponent = br.ReadBytes(0x4);
xParams.Modulus = br.ReadBytes(0x80);
xParams.P = br.ReadBytes(0x40);
xParams.Q = br.ReadBytes(0x40);
xParams.DP = br.ReadBytes(0x40);
xParams.DQ = br.ReadBytes(0x40);
xParams.InverseQ = br.ReadBytes(0x40);
br.close();
br=new BinaryReader(File.OpenRead(f));
br.BaseStream.Position=0x22c;
xHash = new SHA1CryptoServiceProvider().ComputeHash(br.ReadBytes(0x118));
byte[] xrsa=SignatureGenerate(xParams, xHash);
public static byte[] SignatureGenerate(RSAParameters xParam, byte[] xHash)
{
RSACryptoServiceProvider xRSACrypto = new RSACryptoServiceProvider();
RSAPKCS1SignatureFormatter xRSASigFormat = new RSAPKCS1SignatureFormatter();
xRSACrypto.ImportParameters(xParam);
xRSASigFormat.SetHashAlgorithm("SHA1");
xRSASigFormat.SetKey(xRSACrypto);
return xRSASigFormat.CreateSignature(xHash);
}
I'm trying to end up with what's in xrsa
, but using Python. I installed pycrypto, and I'm looking at the documentation, but I'm still missing something obvious. First, the RSA.construct from Crypto.PublicKey only takes six parameters, but not the exponents one and two (DP and DQ). Also, the inputs need to be longs. In the C# code, the values were 128 and 64 bytes long, as opposed to a 4 byte long.
I know this may seem painfully obvious, but I have no idea what I need to do.
I'm working with Python 2.7.3
edit: also, the "message" to be encrypted is a sha1 hash of 0x118 bytes of the file, which contains meta data and a hash of other parts of the file.
edit: Thank you so much mata, I feel I'm closer to getting it working. It still doesn't match the C# signature. In C#, the signature format is being set as SHA1. What is this doing, and can it be done in Python?
回答1:
ok, first: long in python is not 4 byte. in python, long has no predefined size, so using a long to store a 128byte number is no problem. to convert a bytestring to long you can use:
long_value = long(string_value.decode('hex'), 16)
# maybe someone knows a better way?
couldn't it be that the file is in DER form? in that case you simply could simple read the file using:
from Crypto.PublicKey import RSA
with open("keyfile", "rb") as f:
key = RSA.importKey(f.read())
if not, it would probably be best to convert it to PEM or DER, so you don't have to read in the parameters yourself.
anyway, the last three parameters in RSA.construct are optional, specially u
can be calculated as 1/p % q (where p > q)
.
at least from what i've tried, it works even if you only specify the first three parameters.
回答2:
I tried pycrypto and another library, but only ended getting what I wanted working with M2Crypto.
M2Crypto was a serious pain to install on Windows, but it was really easy with the install file here:
http://chandlerproject.org/bin/view/Projects/MeTooCrypto
The download link the to Windows installer is here: http://chandlerproject.org/pub/Projects/MeTooCrypto/M2Crypto-0.21.1.win32-py2.7.exe
来源:https://stackoverflow.com/questions/10329147/trying-to-generate-rsa-signature-with-python-from-working-c-sharp-code