This is a follow up on a question I had asked and thank you to Codename One for implementing promotional offers!
I am having trouble generating the signature. The following snippet of code is what I have to generate the signature, but it is giving a java.lang.IllegalArgumentException: initialisation vector must be the same length as block size
error
byte[] encoded = Base64.decode(key.getBytes("UTF-8"));
KeyFactory keyFactory = KeyFactory.getInstance("EC");
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encoded);
Signature ecdsaSign = Signature.getInstance("SHA256withECDSA");
ecdsaSign.initSign(keyFactory.generatePrivate(keySpec));
ecdsaSign.update(stringToSign.getBytes("UTF-8"));
The key
variable is a string that contains the downloaded PKCS #8 private key from App Store Connect without the "-----BEGIN PRIVATE KEY-----" and "-----END PRIVATE KEY-----" parts/
And the stringToSign
contains a combined string of what is listed on here for promotional offers.
String stringToEncrypt = "appBundleId" + "\u2063"
+ applePromotionalOffer.getKeyIdentifier() + "\u2063"
+ "productIdentifier" + "\u2063"
+ applePromotionalOffer.getOfferIdentifier() + "\u2063"
+ "" + "\u2063"
+ applePromotionalOffer.getNonce() + "\u2063" + applePromotionalOffer.getTimestamp();
There may be problems with my combined string as well
ApplePromotionalOffer applePromotionalOffer = new ApplePromotionalOffer();
applePromotionalOffer.setOfferIdentifier("offerIdentifier");
applePromotionalOffer.setNonce(getGUID().toLowerCase()); // getGUID is a method we have made
applePromotionalOffer.setKeyIdentifier("keyIdentifier");
applePromotionalOffer.setTimestamp(getCurrentEpochInGMTTime()); // getCurrentEpochInGMTTime is a method we have made
Got the promotional offer to show and writing an answer for future developers trying to use the implemented support by Codename One for promotional offers on iOS:
When creating the combined string of appBundleId + '\u2063' + keyIdentifier + '\u2063' + productIdentifier + '\u2063' + offerIdentifier + '\u2063' + appAccountToken + '\u2063' + nonce + '\u2063' + timestamp
, it's best to avoid spacing and special characters for both the productIdentifier and offerIdentifier.
And the offerIdentifier in this combined string should be what is associated to the promotional offer itself, but the productIdentifier(SKU) that you pass into the subscribe(String sku, PromotionalOffer promotionalOffer) should be the "parent" or "base" productIdentifier that the promotional offer is attached to. The same goes with the productIdentifier that goes in the combined string
Thank you Shai Almog, Steve Hannah, and the rest of the Codename One team for the hard work!