I try generate signature with the below code to be used from mobile side in Apple store but the generated signature is invalid.
My Code:
var nonce = Guid.NewGuid().ToString().ToLower();
long timestamp = (long)DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).TotalMilliseconds;
string payload = request.AppBundleID + "\u2063" + request.KeyIdentifier + "\u2063" + request.ProductIdentifier + "\u2063" + request.OfferIdentifier + "\u2063" + request.ApplicationUsername + "\u2063" + nonce + "\u2063" + timestamp;
string keyP8Base64 = System.IO.File.ReadAllText(Path.Combine(webHostEnvironment.WebRootPath, "FileName.p8"))
.Replace("-----BEGIN PRIVATE KEY-----", "")
.Replace("-----END PRIVATE KEY-----", "")
.Replace("\n", "")
.Replace("\r", "");
byte[] keyP8Bytes = Convert.FromBase64String(keyP8Base64);
var privateKey = CngKey.Import(keyP8Bytes, CngKeyBlobFormat.Pkcs8PrivateBlob);
using (ECDsaCng dsa = new ECDsaCng(privateKey))
{
dsa.HashAlgorithm = CngAlgorithm.Sha256;
var unsignedData = Encoding.UTF8.GetBytes(payload);
// Sign data
var signature = dsa.SignData(unsignedData);
// Convert signature to ASN.1 format
var r = new BigInteger(signature.Take(32).ToArray(), isUnsigned: true, isBigEndian: true);
var s = new BigInteger(signature.Skip(32).ToArray(), isUnsigned: true, isBigEndian: true);
var rBytes = r.ToByteArray();
var sBytes = s.ToByteArray();
if (rBytes.Length > 1 && rBytes[0] == 0)
rBytes = rBytes.Skip(1).ToArray();
if (sBytes.Length > 1 && sBytes[0] == 0)
sBytes = sBytes.Skip(1).ToArray();
var derSignature = new byte[6 + rBytes.Length + sBytes.Length];
derSignature[0] = 0x30; // ASN.1 sequence tag
derSignature[1] = (byte)(4 + rBytes.Length + sBytes.Length); // Length of the sequence
derSignature[2] = 0x02; // Integer tag for r
derSignature[3] = (byte)rBytes.Length; // Length of r
Buffer.BlockCopy(rBytes, 0, derSignature, 4, rBytes.Length);
derSignature[4 + rBytes.Length] = 0x02; // Integer tag for s
derSignature[5 + rBytes.Length] = (byte)sBytes.Length; // Length of s
Buffer.BlockCopy(sBytes, 0, derSignature, 6 + rBytes.Length, sBytes.Length);
var derSignatureString = Convert.ToBase64String(derSignature);
if (dsa.VerifyData(unsignedData, signature))
{
return new PromoSignatureResponse
{
KeyIdentifier = request.KeyIdentifier,
Nonce = nonce,
Signature = derSignatureString,
Timestamp = timestamp.ToString()
};
}
Example of the generated signature which is invalid be Apple Store: “MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEvcYI0Wg2vrkuK6jzPNf1qUSkTJeYSNKzu3hJSJhKXuH7c2NMD7QomM5yTdXhs4GFGNmaAPhjS3p3mOXcabfW9g==”