Search code examples
androidiosgoogle-apiapi-keymaui

Google API Key restriction on Xamarin MAUI iOS, Android ( Denied Bundle Identifier with Sha-1 )


We would like to restrict Google Api Keys in our Xamarin iOS, Android Apps.

When we restrict them from Google Cloud, the api denied our request

Why does it not work?


Solution

  • The cause: I did not provide the right informations during my api request

    We add restrictions in Google cloud on bundle identifiers and the Android Sha-1 signature.

    So inside the Header request, We need to send this informations

    using Xamarin.Essentials;
    
    //For iOS
    Headers.Add("X-Ios-Bundle-Identifier", AppInfo.PackageName) 
    
    //For Android
    Headers.Add("X-Android-Package", AppInfo.PackageName)
    Headers.Add("X-Android-Cert", DependencyService.Get<ISignatureHashService>().GetSha1() })
    

    To get the Sha-1 signature, I used the DependencyService that you need to implement it.

            public string GetSha1()
            {
                var Context = Android.App.Application.Context;
    
                if (Build.VERSION.SdkInt >= BuildVersionCodes.P)
                {
                    PackageInfo packageInfo = Context.PackageManager.GetPackageInfo(Context.PackageName, PackageInfoFlags.SigningCertificates);
                    if (packageInfo == null || packageInfo.SigningInfo == null)
                        return string.Empty;
    
                    var signature = packageInfo.SigningInfo.GetSigningCertificateHistory().FirstOrDefault();
                    if (signature != null)
                    {
                        return SignatureDigest(signature);
                    }
    
                }
                else
                {
                    PackageInfo packageInfo = Context.PackageManager.GetPackageInfo(Context.PackageName, PackageInfoFlags.Signatures);
                    if (packageInfo == null || packageInfo.Signatures == null)
                        return string.Empty;
    
                    var signature = Context.PackageManager.GetPackageInfo(Context.PackageName, PackageInfoFlags.Signatures).Signatures.FirstOrDefault();
                    if (signature != null)
                        return SignatureDigest(signature);
                }
                return string.Empty;
            }
    
            private static string SignatureHexa(Android.Content.PM.Signature signature)
            {
                using (SHA1Managed sha1 = new SHA1Managed())
                {
                    var hash = sha1.ComputeHash(signature.ToByteArray());
                    var sb = new StringBuilder(hash.Length * 2);
                    foreach (byte b in hash)
                    {
                        sb.Append(b.ToString("X2"));
                    }
                    return sb.ToString();
                }
            }
    

    For me My App is Sign by GooglePlay, so I don't need multiple signatures

    But if you need to check multiple signers

    if (packageInfo.SigningInfo.HasMultipleSigners)
       {
         foreach (Signature signature in packageInfo.SigningInfo.GetApkContentsSigners())
            {
                //Dostuff
                SignatureHexa(signature);
            }
       }