Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Pay: Public, Private Key Pair generation (Elliptic Curve with NISTP-256)

Android Pay Issue

In Android Pay the process to generate a token from a credit card is as follows:

Generate a public and private key (the calls below return the keys using an Elliptic Curve with NISTP-256 algorithm)

To do this I call ...

public static KeyPair generateKeyPair() {
  KeyPair pair =null;
  try {
    ECGenParameterSpec ecGenSpec = new ECGenParameterSpec("prime256v1");
    java.security.KeyPairGenerator g = KeyPairGenerator.getInstance("EC");
    g.initialize(ecGenSpec, new SecureRandom());
    pair = g.generateKeyPair();
    pair.getPrivate();
    pair.getPublic();
  }catch (Throwable e ){
    e.printStackTrace();
  }
  return pair;
}

… This successfully returns the public and private key, but I am not sure what the format/encoding of the keys is in. I could not find any documentation on this.

Question 1: Is this the right way to generate a public and private key for Android Pay?

Pass the public key in base64 encoded format to the Android Pay createMaskedWalletRequet method (details of this are in the Android Pay documentation)

String publicKey = String (Base64.encodeBase64(pair.getPublic().getEncoded()));

PaymentMethodTokenizationParameters parameters = PaymentMethodTokenizationParameters.newBuilder().setPaymentMethodTokenizationType(PaymentMethodTokenizationType.NETWORK_TOKEN).addParameter("publicKey", publicKey).build();

Here I get the following exception:

03-30 17:02:06.459 3786-15263/? E/WalletClient: Error validating MaskedWalletRequest.paymentMethodTokenizationParameters: first byte of parameter "publicKey" must be 0x04 (which indicates uncompressed point format)

Question 2: Can you please help me understand what I am doing wrong. I think this may be related to a format mismatch, but not sure, and not sure how to fix it.

Appreciate your help!!

like image 252
Shyam Sunder Avatar asked Mar 30 '16 21:03

Shyam Sunder


1 Answers

Answer 1:

According to Android Pay document you can generate public key by OpenSSL like this: https://developers.google.com/android-pay/integration/gateway-processor-integration#example-using-openssl-to-generate-and-format-a-public-keyenter link description here

Then generate private key use

openssl pkcs8 -topk8 -inform PEM -outform PEM -in merchant-key.pem -nocrypt

Or you can use a shell script file.(example: genkey.sh in Android pay quickstart)
Use the following code(copy code to .sh file and double click) you can get private key.

#!/bin/bash

# Generate key.pem file:
openssl ecparam -name prime256v1 -genkey -noout -out key.pem

# Print public and private key in hex form:
openssl ec -in key.pem -text -noout

openssl pkcs8 -topk8 -inform PEM -outform PEM -in key.pem -nocrypt

sleep 2m

Then copy pub string in terminal and replace in this code then save this code to create .sh file again

#!/bin/bash

KEY="04:a9:9b:54:81:b0:67:0d:d3:50:84:e0:d4:d2:29:
    a5:3a:d6:5c:21:ae:5e:dd:58:75:f0:27:63:44:e8:
    a9:86:8d:cf:17:64:63:96:54:34:ed:16:37:c4:37:
    e6:b7:27:ad:06:af:b0:07:d1:b5:66:0a:2a:85:c0:
    71:9e:cc:39:54"

echo $KEY | xxd -r -p | base64
sleep 2m

Then get public key.

Answer 2: You can test by these keys:

Public Key: BKmbVIGwZw3TUITg1NIppTrWXCGuXt1YdfAnY0ToqYaNzxdkY5ZUNO0WN8Q35rcnrQavsAfRtWYKKoXAcZ7MOVQ=

(This public key can pass as a string to MaskedWalletRequet directly)

Private Key: MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgTA/wqrlbeVddorTlaT1AqhALrIBwS+DUdV3N1K1gImqhRANCAASpm1SBsGcN01CE4NTSKaU61lwhrl7dWHXwJ2NE6KmGjc8XZGOWVDTtFjfEN+a3J60Gr7AH0bVmCiqFwHGezDlU

like image 171
Andy P Avatar answered Oct 17 '22 00:10

Andy P