Amazon Pay Integration : Where can I get preSharedEncodedKey? - amazon-product-api

I'm trying to integrate Amazon Pay for receiving merchant payments and I see a method which receives preSharedEncodedKey. But I can't find that key anywhere in document. Where can I find it?
It is mentioned in [22 January 2019 Amazon Pay Integration Guide 26]
private static byte[] encryptMerchantKey(final byte[] key) throws InvalidKeyException, NoSuchAlgorithmException, InvalidKeySpecException, BadPaddingException, IllegalBlockSizeException
{
KeyFactory keyFact = KeyFactory.getInstance(RSA);
KeySpec spec = new X509EncodedKeySpec(org.bouncycastle.util.encoders.Base64.decode("preSharedEncodedKey"));
PublicKey publicKey = keyFact.generatePublic(spec);
Cipher cipher = RSA_THREAD_CIPHER.get();
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
return cipher.doFinal(key);
}
Topic on forum: https://forums.aws.amazon.com/thread.jspa?threadID=104446

As I figured out that the value will be available at AWS merchant account. I can't post the location of it/screenshot as I don't hold the AWS merchant account. But my client gave the "preSharedEncodedKey" which is a long uuid.

Related

authentication AWS method Rest DSL

I have a question regarding Restful services
I need to upload CSV files to an AWS server. I am registered with account.
First I need to obtain an access token and use that to upload the files. I have not coded anything yet, trying to understand the best approach, I so hope to use Camel-Rest-DSL. It is required to communicate with JSON. But, the authentication part has me stuck, I’m pretty sure it uses OAuth2 auth, RestFul web service and JSON, this should just be a client, I was looking at WSS4J for JAX-RS OAuth2 but I don’t know.
I’ve done it with postman, this is the scenario. The username and password are fictional
*Get Access Token
uses POST verb
requires Token Request URL
uses Basic Auth requires Username = Client ID of tenant ( needs to be encoded base64 )
HEADER parm Content-Type = x-www-form-urlencoded
Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'Basic ' + encoded Client ID
Access Token body - grant_type, username, password
Body = username = 5c0642fe-a495-44db-93f7-67034556fa2c061_ingestor
password = 154f0252d166f27b5e21ef171b03212a79f41a0daf3
grant_type = password
#returns the access_token as JSON
POST or upload files
uses POST verb
requires Ingestion URL UploadURL
UploadURL=https://apm-ts-query-svc-prd.app-api.aws-usw02-pr.something.io/v2/time_series/
UploadFolder=upload
headers =
key Authentication "Bearer + access Token" (from request access token above)
key Tenant = TenantUUID
key X-GE-CsvFormat = ODB
# Body
form-data
key file=file
# POST DATA
headers content-type application/json
authorization: "" + token
tenant: "" + tenant
My environment
Jboss Fuse 6.3-310
Karaf version 2.4.0.redhat-630310
JVM
Java Virtual Machine Java HotSpot(TM) 64-Bit Server VM version 25.162-
b12
Version 1.8.0_162
Vendor Oracle Corporation
Operating system
Name Linux version 2.6.32-696.20.1.el6.x86_64
I can't use OAuth2/SAML assertions so I will simply request a token and cache it and use it later. this is my test code
#Override
public void configure() throws Exception {
//Configure the Rest Web Service Component transport to use a REST implementation
restConfiguration() //Configures the REST DSL to use a specific REST implementation
.component("jetty") //Specifies the Camel component to use as the REST transport
.host("localhost") //The hostname to use for exposing the REST service
.port("8282") //The port number to use for exposing the REST service JMX tooling
.scheme("https") //The protocol to use for exposing the REST service
.contextPath("/oauth/token") //Sets a leading context path for the REST services
.bindingMode(RestBindingMode.json) //Enables binding mode for JSON
.jsonDataFormat("json-jackson") //Specifies the component that Camel uses to implement the JSON data format
.dataFormatProperty("prettyPrint", "true"); //set arbitrary properties on the underlying data format component
//Configure the Rest Endpoint
rest("/oauth") //Defines a service using the REST DSL. Each of the verb clauses are terminated by a to() keyword,
//which forwards the incoming message to an endpoint
.post("/token")
.produces("application/json")
.consumes("application/json")
.type(TokenEntities.class)
.route()
.routeId("Get Auth Token Route")
.autoStartup(true)
.id("Get Auth Token Service")
.description("Get Authorization Token")
.process(new UAARequestTokenProcessor())
.to("https://d1e53858-2903-4c21-86c0-95edc7a5cef2.pager-uaa.run.aws-usw02-pr.ice.pager.io/oauth/token")
.to("log:logger?showBody=true")
.to("direct:accessToken")
.endRest();
//Define the Route - from() Defines a regular Camel route.
from("direct:accessToken").to("log:logger?showBody=true"); }
public class UAARequestTokenProcessor implements Processor {
private static final Logger LOG = LoggerFactory.getLogger(UAARequestTokenProcessor.class);
private String clientId = "myClientID";
private String userName = "myUserName";
private String password = "myPassword";
#Override
public void process(Exchange exchange) throws Exception {
LOG.info("Processing UAA token request for " + clientId + " and " + userName);
Message msg = exchange.getOut(); //create outbound message exchange
StringBuilder authHeader = new StringBuilder("Basic ");
authHeader.append(Base64.getEncoder().encodeToString((clientId + ":").getBytes("UTF_8")));
String body = String.format("grant_type=password&username=%s&password=%s",
URLEncoder.encode(userName, "UTF-8"), //Translates a string into x-www-form-urlencoded format
URLEncoder.encode(password, "UTF-8"));
msg.setHeader(Exchange.CONTENT_TYPE, "MediaType.APPLICATION_FORM_URLENCODE");
msg.setHeader("Authorization", authHeader.toString());
msg.setBody(body);
}
}

JSON Web Signature (Ninbus-JOSE-JWT)

I want to do a project with JSON Web Signature (JWS) and i want to send the public key of the certificate used for the signature so that the message can be validated once received with this public key. I am using the Ninbus JOS JWT library. I can sign the JSON object and I can see the public key, but i can not validate it correctly.
This is the code:
// Create RSA-signer with the private key
JWSSigner signer = new RSASSASigner(_signatureKey_); // PrivateKey
com.nimbusds.jose.util.Base64 b64 = new com.nimbusds.jose.util.Base64(_x509certificate.toString()); // X509Certificate
ArrayList<com.nimbusds.jose.util.Base64> certificados = new ArrayList<com.nimbusds.jose.util.Base64>();
certificados.add(b64);
RSAPublicKey _rsaPublicKey = (RSAPublicKey)_x509certificate.getPublicKey(); // Get the public key of the X509Certificate
RSAKey jwk = new com.nimbusds.jose.jwk.RSAKey.Builder( new Base64URL( _rsaPublicKey.getModulus().toString()), new Base64URL( _rsaPublicKey.getPublicExponent().toString()))
.x509CertChain(certificados)
.build();
JWSHeader _jwsHeader = new JWSHeader.Builder(JWSAlgorithm.RS256).
x509CertChain(certificados).
jwk(jwk).
build();
// Prepare JWS object with simple string as payload
JWSObject jwsObject = new JWSObject(_jwsHeader, new Payload(_jsonObject));
// Compute the RSA signature
jwsObject.sign(signer);
// Validation OK : This validation works
JWSVerifier verifier = new RSASSAVerifier(_rsaPublicKey);
boolean signatureValid = jwsObject.verify(verifier); // ---> True, OK
// Now I want to validate the JWSObject getting the public key from the same JWSObject. This validation Fails
JWK _jwk = jwsObject.getHeader().getJWK();
RSAKey _rsakey = (RSAKey)_jwk;
RSAPublicKey _rsaPublicKey2 = _rsakey.toRSAPublicKey();
JWSVerifier verifier2 = new RSASSAVerifier(_rsakey.toRSAPublicKey());
boolean verificado2 = jwsObject.verify(verifier2); // False!
// Another option, this fails too
RSAKey __rsaKey2 = new com.nimbusds.jose.jwk.RSAKey.Builder( _rsakey.toRSAPublicKey() ).x509CertChain(_jwk.getX509CertChain()).build();
JWSVerifier verifier3 = new RSASSAVerifier(__rsaKey2);
boolean verificado3 = jwsObject.verify(verifier3); // False!
The _rsaPublicKey is: "Sun RSA public key, 2048 bits", but when i get it from the JWK (_rsaPublicKey2), I get "Sun RSA public key, 3696 bits" and i don't know why.
Thanks!
On the recipient side, do you validate the X.509 certificate issuer, subject and chain before trusting the key? Signature validation must not be attempted before the recipient is certain that it can trust the certificate included in the JWS.
Another note: Do not include the public JWK in the JWS header. This should only be used for ephemeral public keys in ECDH (a different alg used for JWE). Passing the certificate chain in the JWS header is sufficient, but you must validate it / find out if the certificate can be trusted, before using its public key.
The library will not validate / find out if the certificate can be trusted for you!
If the second signature validation fails, then probably the key used to sign the JWS and the one that came with the X.509 certificate are not the same (as suggested by the different reported lengths - 2048 bits vs. 3696 bits).

Bare Metal Cloud - How to set authorized ssh keys for compute instances?

I have successfully provisioned Bare Metal Cloud compute instances using the following code:
public static Instance createInstance(
ComputeClient computeClient,
String compartmentId,
AvailabilityDomain availabilityDomain,
String instanceName,
Image image,
Shape shape,
Subnet subnet
) {
LaunchInstanceResponse response = computeClient.launchInstance(
LaunchInstanceRequest.builder()
.launchInstanceDetails(
LaunchInstanceDetails.builder()
.availabilityDomain(availabilityDomain.getName())
.compartmentId(compartmentId)
.displayName(instanceName)
.imageId(image.getId())
.shape(shape.getShape())
.subnetId(subnet.getId())
.build())
.build());
return response.getInstance();
}
However, I can't SSH into any instances I create via the code above, because there's no parameter on launchInstance to pass in the public key of my SSH keypair.
How can I tell the instance what SSH public key to allow? I know it must be possible somehow since the console UI allows me to provide the SSH public key as part of instance creation.
According to the launch instance API documentation, you need to pass your SSH public key via the ssh_authorized_keys field of the metadata parameter:
Providing Cloud-Init Metadata
You can use the following metadata key names to provide information to Cloud-Init:
"ssh_authorized_keys" - Provide one or more public SSH keys to be
included in the ~/.ssh/authorized_keys file for the default user on
the instance. Use a newline character to separate multiple keys. The
SSH keys must be in the format necessary for the authorized_keys file
The code for this in the Java SDK looks like this:
public static Instance createInstance(
ComputeClient computeClient,
String compartmentId,
AvailabilityDomain availabilityDomain,
String instanceName,
Image image,
Shape shape,
Subnet subnet
) {
String sshPublicKey = "ssh-rsa AAAAB3NzaC1y...key shortened for example...fdK/ABqxgH7sy3AWgBjfj some description";
Map<String, String> metadata = new HashMap<>();
metadata.put("ssh_authorized_keys", sshPublicKey);
LaunchInstanceResponse response = computeClient.launchInstance(
LaunchInstanceRequest.builder()
.launchInstanceDetails(
LaunchInstanceDetails.builder()
.availabilityDomain(availabilityDomain.getName())
.compartmentId(compartmentId)
.displayName(instanceName)
.imageId(image.getId())
.metadata(metadata)
.shape(shape.getShape())
.subnetId(subnet.getId())
.build())
.build());
return response.getInstance();
}
Then the instance will allow you to SSH to it using the SSH keypair for that public key.

Get group members with an admin account / deprecated GroupsManager class

The class GroupsManager will be turned off by November 20, 2014 https://developers.google.com/apps-script/reference/domain/groups-manager
I am using this class to manage some groups with my admin account as it's allowing access to group members WITHOUT BEING MEMBER OF.
Sample code here:
var group = GroupsManager.getGroup("some-group-name#mydomain.com");
var members = group.getAllMembers();
Using the Groups Service https://developers.google.com/apps-script/reference/groups/ is not an option, as stated in the documentation: "This service allows scripts to access Google Groups. It can be used to query information such as a group's email address, or the list of groups in WHICH THE USER IS MEMBER OF."
Using the AdminSDK as proposed in the GroupsManager "To manage your domain, use the Admin SDK Directory and Admin SDK Reports advanced services instead." is neither an option as there is no method to retrieve the members of a group...
So, anyone has a clue?
Thank you,
Franck
You can use the Admin SDK Directory service to do this. The method AdminDirectory.Members.list lists all the members of a group.
Directory service = null;
try
{
HttpTransport httpTransport = new NetHttpTransport();
JacksonFactory jsonFactory = new JacksonFactory();
GoogleCredential credential = new GoogleCredential.Builder()
.setTransport(httpTransport)
.setJsonFactory(jsonFactory)
.setServiceAccountId(SERVICE_ACCOUNT_EMAIL)
.setServiceAccountScopes(Arrays.asList(DirectoryScopes.ADMIN_DIRECTORY_USER))
.setServiceAccountUser(userEmail)
.setServiceAccountPrivateKeyFromP12File(
new java.io.File(SERVICE_ACCOUNT_PKCS12_FILE_PATH))
.build();
service = new Directory.Builder(httpTransport, jsonFactory, null)
.setHttpRequestInitializer(credential).setApplicationName("ShareFileUSer").build();
}catch(Exception e)
{
System.out.println("Exception is : "+e);
}
Directory.Users.List userList = service.users().list().setCustomer("my_customer").setMaxResults(100);

Issue with google Reseller API sending batch requests

In a special scenario wherein the resold customer who is using Google Vault, GoogleDrive along with Google Apps for Business, and to transfer that customer, as per the documentation (Ref https://developers.google.com/admin-sdk/reseller/v1/how-tos/batch) we're supposed to use Batch Subscription Ordering.
Here is what we're observing so far:
When we try to transfer resold customer which has only one subscription “Google-Apps-For-Business”
a. Then the Batch Ordering (even though its not required) is working.
However when we have to transfer resold customer who has more than on subscription such as “Google-Apps-for-Business” and one or more of “Google Vault”, “Google drive”
a. If we send all features request with Batch Order, the call retunes Error Code: 500 (Internal Server Error)
b. If we send only one request (even though it is wrong as per the documentation) in the Batch Order (the Google-apps-for-business), the call returns expected Error Code: 412 (Precondition Failed): The domain has subscriptions which need to be transferred.
We also tried based on the Google Calendar API Example (Ref https://developers.google.com/admin-sdk/reseller/v1/how-tos/batch) but it also results in the same failure.
Both above suggests either the documentation is wrong or the API doesn't work as per the documentation.
Does anyone have a suggestion?
Here is the sample code
// based on https://code.google.com/p/google-api-java-client/wiki/Batch sample code
Reseller reseller = Reseller.Builder(httpTransport, jsonFactory, credential).setApplicationName("RedResellerAccountSample").build();
JsonBatchCallback<Subscription>; callback = new JsonBatchCallback<Subscription>() {
#Override
public void onSuccess(Subscription t,
HttpHeaders responseHeaders) throws IOException {
// TODO Auto-generated method stub
System.out.println("Success");
}
#Override
public void onFailure(GoogleJsonError e,
HttpHeaders responseHeaders) throws IOException {
// TODO Auto-generated method stub
System.out.println("Failure");
}
};
BatchRequest batchRequest = reseller.batch();
Subscription sub = new Subscription();
sub.setKind("subscriptions#subscription");
sub.setCustomerId("testdomain.com");
Subscription.Plan plan = new Subscription.Plan();
plan.setPlanName("TRIAL");
Seats seats = new Seats();
seats.setKind("subscriptions#seats");
seats.setMaximumNumberOfSeats(10);
sub.setPlan(plan);
sub.setSeats(seats);
sub.setSkuId("Google-Apps-For-Business");
reseller.subscriptions().insert("testdomain.com",sub).setCustomerAuthToken("B40D2EFF4316B703").queue(batchRequest, callback);
Subscription sub2 = new Subscription();
sub2.setKind("subscriptions#subscription");
sub2.setCustomerId("testdomain.com");
Subscription.Plan plan2 = new Subscription.Plan();
plan2.setPlanName("TRIAL");
Seats seats2 = new Seats();
seats2.setKind("subscriptions#seats");
seats2.setMaximumNumberOfSeats(10);
sub2.setPlan(plan);
sub2.setSeats(seats);
sub2.setSkuId("Google-Vault");
reseller.subscriptions().insert("testdomain.com",sub2).setCustomerAuthToken("B40D2EFF4316B703").queue(batchRequest, callback);
//System.out.println(new ObjectMapper().writeValueAsString(batchRequest);
// if we call it fail as we have more than one request queued in the
batchRequest.execute();