Skip to main content

Hi I am seeing this message in my App Store Connect,

  • The SHA-1 intermediate certificate used for signing App Store receipts expires on January 24, 2025. If your app performs on-device receipt validation, make sure it supports the SHA-256 algorithm; alternatively, use the AppTransaction and Transaction APIs to verify App Store transactions. Learn More

I checked the docs but couldn't find anything regarding that.
Is there something we should do?
I am using Flutter in my client with version: 8.2.2.

The same issue


the same issue, and I'm not sure if I have to do something or if everything is ok because I use revenueCat.


Same issue


Same issue.. anyone know?

 


Apple loves pretentious incomprehensible words ))) Same issue. Any help really appreciated!


Same here, had a look at my certificates in App Connect, there is nothing for purchases, so it must be internal to RevenueCat


RevenueCat needs to implement this on the server side


RevenuCat does to implement this on the server side

Any particular version or has it been this way for the last year plus?


Hey there. As for FlutterFlow I got this reply from support:

This will not affect your app. We do not do on-device receipt validation for StoreKit1, and for StoreKit2, we already use the AppTransaction and Transaction APIs to validate receipts. We also already support SHA-256.


Hi all - echoing what ​@gspassky shared, we already support SHA-256 and handle validation using the AppTransaction and Transaction APIs. No change is necessary and your apps will be fine. Please let us know if you have additional questions.

Thanks!


Just want to shed some light for others who are in panic mode to understand this more in deep:


The certificate that is going to expire is on Apple's website [4] under section "Apple Intermediate Certificates". Look for "Worldwide Developer Relations - G8 (Expiring 01/24/2025 00:00:00 UTC)"
Apple also mentions [5] "when the App Store updates the receipt" - I assume this happens only because the receipt was invalid due to certificate expiration (e.g. customer hasn't updated app in a very long time). 
So if you validate signature of the intermediate certificate on device you need to read further.


Your application is signed with multiple certificates (Chain of Trusts1]). You can display them using "codesign --display -vvv /Applications/app_name.app" 
Note the difference between production and sandbox.

Production:
...
Authority=Apple Mac OS Application Signing
Authority=Apple Worldwide Developer Relations Certification Authority
Authority=Apple Root CA
...

Sandbox:
...
Authority=Apple Development: MAREK SECRET (XXXXXXXXXX)
Authority=Apple Worldwide Developer Relations Certification Authority
Authority=Apple Root CA
...

Notice "Apple Worldwide Developer Relations Certification Authority" which is the one we are interested in and the one that is going to expire.

You can extract these certifactes with: 
codesign --display --extract-certificates /Applications/app_name.app
openssl x509 -inform der -in codesign1 -noout -text

There will be 3 files generated. Second file is codesign1 which we used to diplay with openssl
Note the difference between production and sandbox (G5 vs G3).

Production:
...
Issuer: C=US, O=Apple Inc., OU=Apple Certification Authority, CN=Apple Root CA
Validity
    Not Before: Dec 16 19:38:56 2020 GMT
    Not After : Dec 10 00:00:00 2030 GMT
    Subject: CN=Apple Worldwide Developer Relations Certification Authority, OU=G5, O=Apple Inc., C=US
...
Sandbox:
...
Issuer: C=US, O=Apple Inc., OU=Apple Certification Authority, CN=Apple Root CA
Validity
    Not Before: Feb 19 18:13:47 2020 GMT
    Not After : Feb 20 00:00:00 2030 GMT
    Subject: CN=Apple Worldwide Developer Relations Certification Authority, OU=G3, O=Apple Inc., C=US
...


RFC5652 .2] mentions that to verify signature of certificate we need to calculate it ourselves and match it to included message digest. To display available message digests use commands e3]:
codesign --display --dump-cms=cms.asn1 "MyApp.app"
openssl asn1parse -in cms.asn1 -inform der -i

NOTE: The difference is that the Sandbox code misses SHA1 message digest
Production:
...
 4025:d=7  hl=2 l=   9 prim:        OBJECT            :messageDigest
 4036:d=7  hl=2 l=  34 cons:        SET               
 4038:d=8  hl=2 l=  32 prim:         OCTET STRING      3HEX DUMP]:FDCD8C618B187F9B0D0A71F0E631968947252BEBCE7FC07F1E47EDF514A7BB19
 4072:d=6  hl=2 l=  91 cons:       SEQUENCE          
 4074:d=7  hl=2 l=   9 prim:        OBJECT            :1.2.840.113635.100.9.2
 4085:d=7  hl=2 l=  78 cons:        SET               
 4087:d=8  hl=2 l=  29 cons:         SEQUENCE          
 4089:d=9  hl=2 l=   5 prim:          OBJECT            :sha1
 4096:d=9  hl=2 l=  20 prim:          OCTET STRING      HEX DUMP]:CF225963BBB336399E467B26071EC2403DF24B8B
 4118:d=8  hl=2 l=  45 cons:         SEQUENCE          
 4120:d=9  hl=2 l=   9 prim:          OBJECT            :sha256
 4131:d=9  hl=2 l=  32 prim:          OCTET STRING      NHEX DUMP]:A3FCE9D408C2C761FD8D3483E544F94CE8027291D75A3C16A9B3C1BA726DE4EA
...

Sandbox:
...
 4096:d=7  hl=2 l=   9 prim:        OBJECT            :messageDigest
 4107:d=7  hl=2 l=  34 cons:        SET               
 4109:d=8  hl=2 l=  32 prim:         OCTET STRING      =HEX DUMP]:1400A1055B7A95FB5CD3007B0B9F78BA0F1662E46608DB6AC14665C835346BA4
 4143:d=6  hl=2 l=  60 cons:       SEQUENCE          
 4145:d=7  hl=2 l=   9 prim:        OBJECT            :1.2.840.113635.100.9.2
 4156:d=7  hl=2 l=  47 cons:        SET               
 4158:d=8  hl=2 l=  45 cons:         SEQUENCE          
 4160:d=9  hl=2 l=   9 prim:          OBJECT            :sha256
 4171:d=9  hl=2 l=  32 prim:          OCTET STRING       HEX DUMP]:1400A1055B7A95FB5CD3007B0B9F78BA0F1662E46608DB6AC14665C835346BA4
...


What does this all mean? After 24th of January the intermediate certificate won't include the SHA1 message digest. So if your code depends on it (looks if it exists) then you shouldn't waste your time to update your app. Hope I saved you some research time.


PS:I assume customers on lower iOS/macOS which you no longer support will get angry if their app won't run and they can't update iOS/macOS.

Sources:
i1]https://developer.apple.com/documentation/technotes/tn3161-inside-code-signing-certificates#Chain-of-trust
<2]https://datatracker.ietf.org/doc/html/rfc5652#section-5.6
3]https://developer.apple.com/documentation/technotes/tn3161-inside-code-signing-certificates#Cryptographic-Message-Syntax

p4]https://www.apple.com/certificateauthority/

g5]https://developer.apple.com/news/upcoming-requirements/?id=01242025a


Does RevenueCat 4.21.0 fully support this change? If not, what is the minimum version required?
I’m using RNPurchases 5.16.0, which relies on RevenueCat 4.21.0 😫


I am using React Native CLI to develop my app for the Android Play Store, and everything is working fine. I am making the connection to the public API, but when I try to display the paywall screen, I get the error shown in the image. The error code is 23. There is no issue, and I have done the necessary steps, but why am I getting this error? Android Play Store React Native CLI

com.revenuecat.purchases.PurchasesException:There is an issue with your configuration. check the underlying error for more details.


Just want to add there is a simpler way to display that receipt only has SHA256 fingerprint:

codesign -dvvv /Applications/my_app.app

 

Note the difference between hash choices

 

 

Production:
...

CandidateCDHash sha1=cf37459cb661804f7ea697b6ed0628ba970939a2

CandidateCDHashFull sha1=cf37459cb661804f7ea697b6ed0628ba970939a2

CandidateCDHash sha256=1bc30cee6adcc17062c79c8d8045e35a246b2ea3

CandidateCDHashFull sha256=1bc30cee6adcc17062c79c8d8045e35a246b2ea3f716c1dbdef3873d4f9d110a

Hash choices=sha1,sha256


...

Sandbox:
...

CandidateCDHash sha256=7b8a2a3a00a3a66be25cf09ccb41afa65d4fcfd7

CandidateCDHashFull sha256=7b8a2a3a00a3a66be25cf09ccb41afa65d4fcfd78be4a261db0435d43fba163e

Hash choices=sha256


...