ติดตาม apple SKADNetwork ฉันได้สร้างรหัสส่วนตัวและรหัสสาธารณะด้วยคำสั่งนี้
openssl ecparam -name prime192v1 -genkey -noout -out private_key.pem
openssl ec -in private_key.pem -pubout -out public_key.pem
ฉันสามารถสร้างลายเซ็นที่ถูกต้องด้วย python ตามโครงการนี้ https://github.com/singular-labs/Singular-SKAdNetwork-App/tree/master/skadnetwork-server
แต่เมื่อฉันพยายามสร้างลายเซ็นผ่านไลบรารี c# bouncycastle ฉันจะได้ผลลัพธ์ที่แตกต่างออกไปหากฉันใช้ข้อมูลเดียวกัน
การทดสอบ BOUNCYCASTLE
public static AsymmetricCipherKeyPair ReadAsymmetricPrivateKeyParameter(string pemFilename)
{
var fileStream = System.IO.File.OpenText(pemFilename);
var pemReader = new Org.BouncyCastle.OpenSsl.PemReader(fileStream);
var KeyParameter = (AsymmetricCipherKeyPair)pemReader.ReadObject();
return (AsymmetricCipherKeyPair)KeyParameter;
}
static void Main(string[] args)
{
AsymmetricCipherKeyPair pkey = ReadAsymmetricPrivateKeyParameter("private_key.pem");
string pars = getParamsSignature("2.0", "xxxxxxx.skadnetwork", "10", "302584613", "0a97ad57-87d1-49e7-b166-9152c708251b", "1613749507007", "0");
Sign(pkey, "", pars);
Console.Read();
}
static string getParamsSignature(string version, string ad_network_id, string campaign_id, string target_app_id, string nonce, string timestamp, string source_app_id)
{
string[] p = new string[] {
version,
ad_network_id,
campaign_id,
target_app_id,
nonce,
source_app_id,
timestamp
};
return string.Join("\u2063", p);
}
public static bool Sign(AsymmetricCipherKeyPair pubKey, string msg)
{
try
{
ECDomainParameters aa;
byte[] msgBytes = Encoding.UTF8.GetBytes(msg);
ISigner signer = SignerUtilities.GetSigner("SHA-256withECDSA");
signer.Init(true, pubKey.Private);
signer.BlockUpdate(msgBytes, 0, msgBytes.Length);
byte[] sigBsdytes = signer.GenerateSignature();
var signature = Convert.ToBase64String(sigBsdytes);
//MDUCGQDgqw1YQN/vvHTxXXTpovNYUnACzkFrXJwCGCXAnr3TUbbqIUr6cBamymrypcQET5RR7Q==
}
catch (Exception exc)
{
Console.WriteLine("Verification failed with the error: " + exc.ToString());
return false;
}
return false;
}
การทดสอบ .NET CORE 3
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
string pars = getParamsSignature("2.0", "xxxxx.skadnetwork", "10", "302584613", "0a97ad57-87d1-49e7-b166-9152c708251b", "1613749507007", "0");
//bool aaaaa = VerifySignature(aa, attribution_signature, pars);
string eccPem = File.ReadAllText("private_key.pem");
var key = ECDsa.Create(ECCurve.CreateFromValue("1.2.840.10045.3.1.1"));
key.ImportECPrivateKey(Convert.FromBase64String(eccPem), out _);
var signed = key.SignData(Encoding.UTF8.GetBytes(pars), HashAlgorithmName.SHA256);
var hash = Convert.ToBase64String(signed);
}
ด้วยการทดสอบ .net.core ผลลัพธ์จะแย่ยิ่งกว่าเดิมเนื่องจากโทเค็นมีการเปลี่ยนแปลงในการดำเนินการแต่ละครั้ง ฉันคิดว่ามีพฤติกรรมสุ่ม
#BOUNCYCASTLE รูปแบบการทดสอบที่กำหนด R|S และ ASN1
byte[] msgBytes = Encoding.UTF8.GetBytes(msg);
ECDsaSigner signer = new ECDsaSigner(new HMacDsaKCalculator(new Sha256Digest()));
signer.Init(true, pubKey.Private);
var sigBsdytes = signer.GenerateSignature(msgBytes);
//SIGNATURE (R|S)
Console.WriteLine( Convert.ToBase64String(sigBsdytes.SelectMany(a => a.ToByteArray()).ToArray()));
//SIGNATURE (ASN1)
var s = new MemoryStream();
try
{
DerSequenceGenerator seq = new DerSequenceGenerator(s);
seq.AddObject(new DerInteger(sigBsdytes[0]));
seq.AddObject(new DerInteger(sigBsdytes[1]));
seq.Close();
var signature = Convert.ToBase64String(s.ToArray());
Console.WriteLine(signature);
}
catch (IOException e)
{
}
ยังคงมีผลลัพธ์ที่แตกต่างจากไลบรารี python FastECDSA หากสตริงอินพุตเป็นสตริงเดียวกัน
โซลูชันการอัปเดต: ขอบคุณความคิดเห็น @topaco
var crypt = new System.Security.Cryptography.SHA256Managed();
byte[] msgBytes = crypt.ComputeHash(Encoding.UTF8.GetBytes(msg));
ECDsaSigner signer = new ECDsaSigner(new HMacDsaKCalculator(new Sha256Digest()));
signer.Init(true, pubKey.Private);
var sigBsdytes = signer.GenerateSignature(msgBytes);
//SIGNATURE (ASN1)
var s = new MemoryStream();
try
{
DerSequenceGenerator seq = new DerSequenceGenerator(s);
seq.AddObject(new DerInteger(sigBsdytes[0]));
seq.AddObject(new DerInteger(sigBsdytes[1]));
seq.Close();
var signature = Convert.ToBase64String(s.ToArray());
Console.WriteLine(signature);
}
catch (IOException e)
{
}
ECDsaSigner
ไม่ได้แฮชโดยปริยาย กล่าวคือ คุณต้องแฮชข้อความในโค้ด C# อย่างชัดเจนด้วย SHA256 ก่อนลงนาม ผลลัพธ์จากโค้ด Python และ C# จะเหมือนกันบนเครื่องของฉัน - person user 9014097   schedule 22.02.2021