diff --git a/CorePush/Apple/ApnSender.cs b/CorePush/Apple/ApnSender.cs
index 9d4dd80..ed74c07 100644
--- a/CorePush/Apple/ApnSender.cs
+++ b/CorePush/Apple/ApnSender.cs
@@ -120,15 +120,28 @@ private string GetJwtToken()
private string CreateJwtToken()
{
- var header = serializer.Serialize(new { alg = "ES256", kid = CryptoHelper.CleanP8Key(settings.P8PrivateKeyId) });
+ var header = serializer.Serialize(new { alg = "ES256", kid = settings.P8PrivateKeyIdClean });
var payload = serializer.Serialize(new { iss = settings.TeamId, iat = CryptoHelper.GetEpochTimestamp() });
var headerBase64 = Base64UrlEncode(header);
var payloadBase64 = Base64UrlEncode(payload);
var unsignedJwtData = $"{headerBase64}.{payloadBase64}";
var unsignedJwtBytes = Encoding.UTF8.GetBytes(unsignedJwtData);
-
- var privateKeyBytes = Convert.FromBase64String(CryptoHelper.CleanP8Key(settings.P8PrivateKey));
- var keyParams = (ECPrivateKeyParameters) PrivateKeyFactory.CreateKey(privateKeyBytes);
+
+ ECPrivateKeyParameters keyParams = settings.CachedP8PrivateKeyParams as ECPrivateKeyParameters;
+ if (keyParams == null)
+ {
+ lock(settings)
+ {
+ keyParams = settings.CachedP8PrivateKeyParams as ECPrivateKeyParameters;
+ if (keyParams == null)
+ {
+ var privateKeyBytes = Convert.FromBase64String(CryptoHelper.CleanP8Key(settings.P8PrivateKey));
+ keyParams = (ECPrivateKeyParameters)PrivateKeyFactory.CreateKey(privateKeyBytes);
+ settings.CachedP8PrivateKeyParams = keyParams;
+ }
+ }
+ }
+
var q = keyParams.Parameters.G.Multiply(keyParams.D).Normalize();
using var dsa = ECDsa.Create(new ECParameters
diff --git a/CorePush/Apple/ApnSettings.cs b/CorePush/Apple/ApnSettings.cs
index 5c0cf76..655c6ce 100644
--- a/CorePush/Apple/ApnSettings.cs
+++ b/CorePush/Apple/ApnSettings.cs
@@ -1,29 +1,68 @@
+using CorePush.Utils;
+
namespace CorePush.Apple;
+#nullable enable
+
public class ApnSettings
{
+ private string? _P8PrivateKey = null;
+ private string? _P8PrivateKeyId = null;
+ private string? _P8PrivateKeyIdClean = null;
+
///
/// p8 certificate string
///
- public string P8PrivateKey { get; set; }
+ public string? P8PrivateKey
+ {
+ get
+ {
+ return _P8PrivateKey;
+ }
+ set
+ {
+ lock (this)
+ {
+ _P8PrivateKey = value;
+ CachedP8PrivateKeyParams = null;
+ }
+ }
+ }
///
/// 10 digit p8 certificate id. Usually a part of a downloadable certificate filename
///
- public string P8PrivateKeyId { get; set; }
+ public string? P8PrivateKeyId
+ {
+ get
+ {
+ return _P8PrivateKeyId;
+ }
+ set
+ {
+ lock (this)
+ {
+ _P8PrivateKeyId = value;
+ _P8PrivateKeyIdClean = CryptoHelper.CleanP8Key(value);
+ }
+ }
+ }
///
/// Apple 10 digit team id
///
- public string TeamId { get; set; }
+ public string? TeamId { get; set; }
///
/// App slug / bundle name
///
- public string AppBundleIdentifier { get; set; }
+ public string? AppBundleIdentifier { get; set; }
///
/// Development or Production server
///
public ApnServerType ServerType { get; set; }
+
+ internal string? P8PrivateKeyIdClean { get { return _P8PrivateKeyIdClean; } }
+ internal object? CachedP8PrivateKeyParams;
}
\ No newline at end of file
diff --git a/CorePush/Firebase/FirebaseSender.cs b/CorePush/Firebase/FirebaseSender.cs
index 02ce3c0..bd1207a 100644
--- a/CorePush/Firebase/FirebaseSender.cs
+++ b/CorePush/Firebase/FirebaseSender.cs
@@ -165,7 +165,20 @@ private string GetMasterToken()
var unsignedJwtData = $"{headerBase64}.{payloadBase64}";
var unsignedJwtBytes = Encoding.UTF8.GetBytes(unsignedJwtData);
- var privateKey = ParsePkcs8PrivateKeyPem(settings.PrivateKey);
+ var privateKey = settings._CachedPivateKey as AsymmetricKeyParameter;
+ if (privateKey == null)
+ {
+ lock(settings)
+ {
+ privateKey = settings._CachedPivateKey as AsymmetricKeyParameter;
+ if (privateKey == null)
+ {
+ privateKey = ParsePkcs8PrivateKeyPem(settings.PrivateKey);
+ settings._CachedPivateKey = privateKey;
+ }
+ }
+ }
+
var signer = new RsaDigestSigner(new Org.BouncyCastle.Crypto.Digests.Sha256Digest());
signer.Init(true, privateKey);
signer.BlockUpdate(unsignedJwtBytes, 0, unsignedJwtBytes.Length);
diff --git a/CorePush/Firebase/FirebaseSettings.cs b/CorePush/Firebase/FirebaseSettings.cs
index 4e195d4..621c663 100644
--- a/CorePush/Firebase/FirebaseSettings.cs
+++ b/CorePush/Firebase/FirebaseSettings.cs
@@ -1,5 +1,7 @@
using System.Text.Json.Serialization;
+#nullable enable
+
namespace CorePush.Firebase;
public record FirebaseSettings(
@@ -7,4 +9,7 @@ public record FirebaseSettings(
[property: JsonPropertyName("private_key")] string PrivateKey,
[property: JsonPropertyName("client_email")] string ClientEmail,
[property: JsonPropertyName("token_uri")] string TokenUri
-);
\ No newline at end of file
+)
+{
+ internal object? _CachedPivateKey;
+}
\ No newline at end of file