@Test public void testShouldFailIfSignatureWasChanged() throws Exception { EcdsaSignJce signer = new EcdsaSignJce( EllipticCurves.getEcPrivateKey(Base64.decode(GOOGLE_SIGNING_PRIVATE_KEY_PKCS8_BASE64)), HashType.SHA256, EcdsaEncoding.DER); RewardedAdsVerifier verifier = new RewardedAdsVerifier.Builder() .setVerifyingPublicKeys(GOOGLE_VERIFYING_PUBLIC_KEYS_JSON) .build(); byte[] validSig = signer.sign(REWARD_URL.getBytes(UTF_8)); for (int i = 0; i < validSig.length; i++) { byte[] modifiedSig = Arrays.copyOf(validSig, validSig.length); modifiedSig[i] = (byte) (modifiedSig[i] ^ 0xff); String modifiedUrl = buildUrl(REWARD_URL, modifiedSig, KEY_ID); try { verifier.verify(modifiedUrl); fail("Expected GeneralSecurityException"); } catch (GeneralSecurityException e) { System.out.println(e); } } }
public void verify(String rewardUrl) throws GeneralSecurityException { URI uri; try { uri = new URI(rewardUrl); } catch (URISyntaxException ex) { throw new GeneralSecurityException(ex); } String queryString = uri.getQuery(); int i = queryString.indexOf(SIGNATURE_PARAM_NAME); if (i <= 0 || queryString.charAt(i - 1) != '&') { throw new GeneralSecurityException( "signature and key id must be the last two query parameters"); } byte[] tbsData = queryString.substring(0, i - 1 ).getBytes(UTF_8); String sigAndKeyId = queryString.substring(i); i = sigAndKeyId.indexOf(KEY_ID_PARAM_NAME); if (i == -1 || sigAndKeyId.charAt(i - 1) != '&') { throw new GeneralSecurityException( "signature and key id must be the last two query parameters"); } String sig = sigAndKeyId.substring( SIGNATURE_PARAM_NAME.length(), i - 1 ); try { long keyId = Long.parseLong(sigAndKeyId.substring(i + KEY_ID_PARAM_NAME.length())); verify(tbsData, keyId, Base64.urlSafeDecode(sig)); } catch (NumberFormatException ex) { throw new GeneralSecurityException("key_id must be a long"); } }
RewardedAdsVerifier { public void verify(String rewardUrl) throws GeneralSecurityException { URI uri; try { uri = new URI(rewardUrl); } catch (URISyntaxException ex) { throw new GeneralSecurityException(ex); } String queryString = uri.getQuery(); int i = queryString.indexOf(SIGNATURE_PARAM_NAME); if (i <= 0 || queryString.charAt(i - 1) != '&') { throw new GeneralSecurityException( "signature and key id must be the last two query parameters"); } byte[] tbsData = queryString.substring(0, i - 1 ).getBytes(UTF_8); String sigAndKeyId = queryString.substring(i); i = sigAndKeyId.indexOf(KEY_ID_PARAM_NAME); if (i == -1 || sigAndKeyId.charAt(i - 1) != '&') { throw new GeneralSecurityException( "signature and key id must be the last two query parameters"); } String sig = sigAndKeyId.substring( SIGNATURE_PARAM_NAME.length(), i - 1 ); try { long keyId = Long.parseLong(sigAndKeyId.substring(i + KEY_ID_PARAM_NAME.length())); verify(tbsData, keyId, Base64.urlSafeDecode(sig)); } catch (NumberFormatException ex) { throw new GeneralSecurityException("key_id must be a long"); } } }
RewardedAdsVerifier { public void verify(String rewardUrl) throws GeneralSecurityException { URI uri; try { uri = new URI(rewardUrl); } catch (URISyntaxException ex) { throw new GeneralSecurityException(ex); } String queryString = uri.getQuery(); int i = queryString.indexOf(SIGNATURE_PARAM_NAME); if (i <= 0 || queryString.charAt(i - 1) != '&') { throw new GeneralSecurityException( "signature and key id must be the last two query parameters"); } byte[] tbsData = queryString.substring(0, i - 1 ).getBytes(UTF_8); String sigAndKeyId = queryString.substring(i); i = sigAndKeyId.indexOf(KEY_ID_PARAM_NAME); if (i == -1 || sigAndKeyId.charAt(i - 1) != '&') { throw new GeneralSecurityException( "signature and key id must be the last two query parameters"); } String sig = sigAndKeyId.substring( SIGNATURE_PARAM_NAME.length(), i - 1 ); try { long keyId = Long.parseLong(sigAndKeyId.substring(i + KEY_ID_PARAM_NAME.length())); verify(tbsData, keyId, Base64.urlSafeDecode(sig)); } catch (NumberFormatException ex) { throw new GeneralSecurityException("key_id must be a long"); } } RewardedAdsVerifier(List<VerifyingPublicKeysProvider> verifyingPublicKeysProviders); private  RewardedAdsVerifier(Builder builder); }
RewardedAdsVerifier { public void verify(String rewardUrl) throws GeneralSecurityException { URI uri; try { uri = new URI(rewardUrl); } catch (URISyntaxException ex) { throw new GeneralSecurityException(ex); } String queryString = uri.getQuery(); int i = queryString.indexOf(SIGNATURE_PARAM_NAME); if (i <= 0 || queryString.charAt(i - 1) != '&') { throw new GeneralSecurityException( "signature and key id must be the last two query parameters"); } byte[] tbsData = queryString.substring(0, i - 1 ).getBytes(UTF_8); String sigAndKeyId = queryString.substring(i); i = sigAndKeyId.indexOf(KEY_ID_PARAM_NAME); if (i == -1 || sigAndKeyId.charAt(i - 1) != '&') { throw new GeneralSecurityException( "signature and key id must be the last two query parameters"); } String sig = sigAndKeyId.substring( SIGNATURE_PARAM_NAME.length(), i - 1 ); try { long keyId = Long.parseLong(sigAndKeyId.substring(i + KEY_ID_PARAM_NAME.length())); verify(tbsData, keyId, Base64.urlSafeDecode(sig)); } catch (NumberFormatException ex) { throw new GeneralSecurityException("key_id must be a long"); } } RewardedAdsVerifier(List<VerifyingPublicKeysProvider> verifyingPublicKeysProviders); private  RewardedAdsVerifier(Builder builder); void verify(String rewardUrl); }
RewardedAdsVerifier { public void verify(String rewardUrl) throws GeneralSecurityException { URI uri; try { uri = new URI(rewardUrl); } catch (URISyntaxException ex) { throw new GeneralSecurityException(ex); } String queryString = uri.getQuery(); int i = queryString.indexOf(SIGNATURE_PARAM_NAME); if (i <= 0 || queryString.charAt(i - 1) != '&') { throw new GeneralSecurityException( "signature and key id must be the last two query parameters"); } byte[] tbsData = queryString.substring(0, i - 1 ).getBytes(UTF_8); String sigAndKeyId = queryString.substring(i); i = sigAndKeyId.indexOf(KEY_ID_PARAM_NAME); if (i == -1 || sigAndKeyId.charAt(i - 1) != '&') { throw new GeneralSecurityException( "signature and key id must be the last two query parameters"); } String sig = sigAndKeyId.substring( SIGNATURE_PARAM_NAME.length(), i - 1 ); try { long keyId = Long.parseLong(sigAndKeyId.substring(i + KEY_ID_PARAM_NAME.length())); verify(tbsData, keyId, Base64.urlSafeDecode(sig)); } catch (NumberFormatException ex) { throw new GeneralSecurityException("key_id must be a long"); } } RewardedAdsVerifier(List<VerifyingPublicKeysProvider> verifyingPublicKeysProviders); private  RewardedAdsVerifier(Builder builder); void verify(String rewardUrl); static final String SIGNATURE_PARAM_NAME; static final String KEY_ID_PARAM_NAME; static final String PUBLIC_KEYS_URL_PROD; static final String PUBLIC_KEYS_URL_TEST; static final KeysDownloader KEYS_DOWNLOADER_INSTANCE_PROD; static final KeysDownloader KEYS_DOWNLOADER_INSTANCE_TEST; }