using System; using System.Collections.Generic; using System.Linq; using System.Security.Cryptography; using System.Text; using Jose; using Newtonsoft.Json; namespace Sony.Filtr.AppleMusic { public class AppleMusicTokenGenerator { private readonly string _privateKey; private readonly string _kid; private readonly string _iss; public AppleMusicTokenGenerator(string privateKey, string kid, string iss) { _privateKey = privateKey; _kid = kid; _iss = iss; } public string GetJwtToken() { var headers = JsonConvert.SerializeObject(new Dictionary() { { "alg", "ES256" }, { "kid", _kid }, }); var issued = DateTimeOffset.UtcNow.ToUnixTimeSeconds(); var expiresAt = DateTimeOffset.UtcNow.AddMonths(3).ToUnixTimeSeconds(); var payload = JsonConvert.SerializeObject(new Dictionary() { { "iss", _iss }, { "iat", issued }, { "exp", expiresAt } }); using (ECDsa key = ECDsa.Create()) { key.ImportPkcs8PrivateKey(Convert.FromBase64String(_privateKey), out _); var headerBase64 = Convert.ToBase64String(Encoding.UTF8.GetBytes(headers)); var payloadBasae64 = Convert.ToBase64String(Encoding.UTF8.GetBytes(payload)); var unsignedJwtData = $"{headerBase64}.{payloadBasae64}"; byte[] encodedRequest = Encoding.UTF8.GetBytes(unsignedJwtData); byte[] signature = key.SignData(encodedRequest, HashAlgorithmName.SHA256); return $"{unsignedJwtData}.{Convert.ToBase64String(signature)}"; } } } }