'JAVA Generating a Signature for Apple Promotional Offers

I'm trying to generate a signature to be returned to the mobile application in order to validate a promotional offer with the App Store.

Apple documentation :doc

However, the validation failed in the mobile application with invalid signature error.

Below, the method that aims to generate the signature

    public static final String BEGIN_PRIVATE_KEY = "-----BEGIN PRIVATE KEY-----";
    public static final String END_PRIVATE_KEY = "-----END PRIVATE KEY-----";
    public static final String EC = "EC";
    public static final String SHA_256_WITH_ECDSA = "SHA256withECDSA";
    public static final String SEPARATOR = "\\u2063";
    public static final String P8_KEY_PATH = "classpath:keys/AuthKey.p8";
    
         private void setSignature(SubscriptionDto subscription , String username) {
    
    
                        String productId = subscription.getAppleIdentifier();
    
                        UUID nonce = UUID.randomUUID();
                        Instant instant = Instant.now();
                        long timestamp = instant.toEpochMilli();
                        String offerId = getOfferId(subscription);
                        String payload = buildPayload(productId, nonce, timestamp, offerId, username);
                       
                        Signature ecdsaSign = Signature.getInstance(SHA_256_WITH_ECDSA);
                        ecdsaSign.initSign(getPrivateKey());
                        ecdsaSign.update(payload.getBytes(StandardCharsets.UTF_8));
                        byte[] signature = ecdsaSign.sign();
                        
                        String sig = Base64.getEncoder().encodeToString(signature); // returned signature
                        verify(sig, payload);

                                        
        }
    
      
        private String buildPayload(String productId, UUID nonce, long timestamp, String offerId, String username) {
            return String.join(SEPARATOR, bundleId,
                    keyId,
                    productId,
                    offerId,
                    username!=null?username:"",
                    nonce.toString().toLowerCase(),
                    Long.toString(timestamp));
        }
    
      
        public PrivateKey getPrivateKey() throws Exception {
            String key = FileUtils.readFileToString(ResourceUtils.getFile(P8_KEY_PATH),
                    Charset.defaultCharset());
    
            String privateKeyPEM = key
                    .replace(BEGIN_PRIVATE_KEY, "")
                    .replaceAll(System.lineSeparator(), "")
                    .replace(END_PRIVATE_KEY, "");
    
            byte[] encoded = Base64.getDecoder().decode(privateKeyPEM);
            KeyFactory keyFactory = KeyFactory.getInstance(EC);
            PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encoded);
            return keyFactory.generatePrivate(keySpec);
        }

Any idea please ?



Solution 1:[1]

You need to update your invisible separator

from this

public static final String SEPARATOR = "\\u2063";

to this

public static final String SEPARATOR = "\u2063"; 

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Waleed Hassan