Am trying to integrate finland's checkout api in my project. It always gives me 401 (i.e., as per API my Hmac calculation failed).
Her is the link to api where they calculated Hmac using nodejs and php.
https://checkoutfinland.github.io/psp-api/#/examples
Can anyone help me where am going wron in my java code. Here is my code:
// Make sure all check-out headers are in alphabetical order and
// all header keys must be in lower case
// if request contains body - it should be valid JSON and content-type header should be included
Map<String, String> headersMap = new TreeMap<>();
headersMap.put("checkout-account", "375917");
headersMap.put("checkout-algorithm", "sha256");
headersMap.put("checkout-method", "POST");
headersMap.put("checkout-nonce", String.valueOf(UUID.randomUUID())); // unique identifier for this request
headersMap.put("checkout-timestamp", ZonedDateTime.now( ZoneOffset.UTC ).format( DateTimeFormatter.ISO_INSTANT )); // ISO 8601 format date time
/**
* All API calls need to be signed using HMAC and SHA-256 or SHA-512
*/
String headers[] = new String[headersMap.size()];
int index = 0;
for(Map.Entry<String, String> headersEntry: headersMap.entrySet()){
headers[index++] = headersEntry.getKey()+":"+headersEntry.getValue();
}
Map<String, Object> requestBody = new HashMap<>();
requestBody.put("stamp", "29858472952");
requestBody.put("reference", "9187445");
requestBody.put("amount", 1500);
requestBody.put("currency", "EUR");
requestBody.put("language", "FI");
List<List<Map<String, Object>>> itemsList = new ArrayList<>();
List<Map<String, Object>> item = new ArrayList<>();
Map<String, Object> itemObj = new HashMap<>();
itemObj.put("unitPrice", 1500);
itemObj.put("units",1);
itemObj.put("vatPercentage", 5);
itemObj.put("productCode", "#1234");
itemObj.put("deliveryDate", "2018-09-01");
item.add(itemObj);
itemsList.add(item);
requestBody.put("items", itemsList);
Map<String, Object> customer = new HashMap<>();
customer.put("email", "test.customer#example.com");
requestBody.put("customer", customer);
Map<String, Object> redirectUrls = new HashMap<>();
redirectUrls.put("success","example.com");
redirectUrls.put("cancel","example.com");
requestBody.put("redirectUrls",redirectUrls);
String body = new ObjectMapper().writeValueAsString(requestBody);
String data = String.join("\n", ArrayUtils.addAll(headers, body));
String hmacSha256Hash = calculateHmacSha256("SAIPPUAKAUPPIAS", data);
if(hmacSha256Hash != null){
headersMap.put("content-type", "application/json; charset=utf-8");
headersMap.put("signature", hmacSha256Hash);
// Make network call checkout api
}
Hmac Calculation method:
private String calculateHmacSha256(String key, String data){
String resultHash = null;
try {
Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
SecretKeySpec secret_key = new SecretKeySpec(key.getBytes("UTF-8"),"HmacSHA256");
sha256_HMAC.init(secret_key);
resultHash = Hex.encodeHexString(sha256_HMAC.doFinal(data.getBytes()));
} catch (Exception e) {
System.out.println("Error calculating HmacSHA256 hash for data data"+ e);
}
return resultHash;
}
I implemented it identical to the one which they have in the examples.
Related
I was creating a signed URL for uploading an audio file. Url is used in Android apps. It's migration from azure to GCP so can write azure code here:
String cdnUrl = fileUploadConfig.has(containerName) ? fileUploadConfig.getString(containerName)
: Constants.AZURE_STORAGE_URL;
BlobServiceClient client = new BlobServiceClientBuilder().connectionString(storageConnectionString)
.buildClient();
BlobClient blobClient = client.getBlobContainerClient(containerName).getBlobClient(key);
BlobSasPermission blobSasPermission = new BlobSasPermission().setWritePermission(true);
OffsetDateTime expiryTime = OffsetDateTime.now().plusDays(1);
BlobServiceSasSignatureValues values = new BlobServiceSasSignatureValues(expiryTime, blobSasPermission)
.setStartTime(OffsetDateTime.now());
String signature = blobClient.generateSas(values);
Map<String,String> headerMap = new HashMap<String,String>(){{
put("x-ms-blob-type","BlockBlob");
}};
JSONObject res = new JSONObject();
System.out.println(blobClient.getBlobUrl());
cdnUrl += key;
res.put("presignedUrl", blobClient.getBlobUrl() + "?" + signature);
res.put("cdnUrl", cdnUrl);
res.put("header",new JSONObject(headerMap) );
return res.toString();
When I am transforming it into GCP, I am writing the following code:
String cdnUrl;
try {
cdnUrl = KhabriUtils.getSecret("s3-cdn-mapping-" + containerName);
} catch (Exception e) {
// TODO Auto-generated catch block
cdnUrl = Constants.GCP_STORAGE_URL;
e.printStackTrace();
}
Storage storage = StorageOptions.newBuilder().setProjectId(Constants.GCP_PROJECT_ID).build().getService();
// Define resource
BlobInfo blobInfo = BlobInfo.newBuilder(BlobId.of(containerName, key)).build();
// Generate Signed URL
Map<String, String> extensionHeaders = new HashMap<>();
extensionHeaders.put("Content-Type", "application/octet-stream");
URL url =
storage.signUrl(
blobInfo,
15,
TimeUnit.MINUTES,
Storage.SignUrlOption.httpMethod(HttpMethod.PUT),
Storage.SignUrlOption.withExtHeaders(extensionHeaders),
Storage.SignUrlOption.withV4Signature());
JSONObject res = new JSONObject();
cdnUrl += key;
res.put("presignedUrl", url);
res.put("cdnUrl", cdnUrl);
res.put("header", new JSONObject(extensionHeaders));
return res.toString();
It is giving me an error
Server response: code 403, body SignatureDoesNotMatchThe request signature we calculated does not match the signature you provided. Check your Google secret key and signing method.GOOG4-RSA-SHA256
Tried to see if there is any permission missing.
What I try to achieve:
iOS client sends a JWT token to the backend.
Backend (Java) calls https://appleid.apple.com/auth/token to verify the token.
what I have so far:
to make Apple verification call:
restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
map.add("client_id", clientId); // app_id like com.app.id
String token = generateJWT(); // generated jwt
map.add("client_secret", token);
map.add("grant_type", "authorization_code");
map.add("code", authorizationCode); // JWT code we got from iOS
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers);
final String appleAuthURL = "https://appleid.apple.com/auth/token";
String response = restTemplate.postForObject(appleAuthURL, request, String.class);
token generation:
final PrivateKey privateKey = getPrivateKey();
final int expiration = 1000 * 60 * 5;
String token = Jwts.builder()
.setHeaderParam(JwsHeader.KEY_ID, keyId) // key id I got from Apple
.setIssuer(teamId)
.setAudience("https://appleid.apple.com")
.setSubject(clientId) // app id com.app.id
.setExpiration(new Date(System.currentTimeMillis() + expiration))
.setIssuedAt(new Date(System.currentTimeMillis()))
.signWith(SignatureAlgorithm.ES256, privateKey) // ECDSA using P-256 and SHA-256
.compact();
return token;
to get my private key from the file:
final Reader pemReader = new StringReader(getKeyData());
final PEMParser pemParser = new PEMParser(pemReader);
final JcaPEMKeyConverter converter = new JcaPEMKeyConverter();
final PrivateKeyInfo object = (PrivateKeyInfo) pemParser.readObject();
final PrivateKey pKey = converter.getPrivateKey(object);
I confirmed my JWT has all required fields:
{
"kid": "SAME KEY AS MY KEY ID",
"alg": "ES256"
}
{
"iss": "Blahblah",
"aud": "https://appleid.apple.com",
"sub": "com.app.id",
"exp": 1578513833,
"iat": 1578513533
}
This line caught my attention:
map.add("code", authorizationCode); // JWT code we got from iOS
The authorizationCode is not a jwt
JSON Web Tokens consist of 3 parts separated by dots
but the authorizationCode has 4 parts like this:
text1.text2.0.text3
You are probably using the identityToken from the iOS app instead of the authorizationCode
This is how you retrieve it:
let authorizationCode = String(data: appleIDCredential.authorizationCode!, encoding: .utf8)!
print("authorizationCode: \(authorizationCode)")
Also good to have the following in mind for those who might come here after getting the same invalid_client error:
kid is the id for the private key from developer.apple.com/account/resources/authkeys/list
keyFile is the file holding the private key downloaded from developer.apple.com
teamID can be found by logging in to developer.apple.com and clicking on account, the teamID can be seen in the upper right corner
the value in aud should be https://appleid.apple.com
app_id is the bundle identifier for the app
In case it might help, here is a working solution in python to create a client_secret:
# $ pip install pyjwt
import jwt
import time
kid = "myKeyId"
keyFile = "/pathToFile/AuthKey.p8"
key = ""
with open(keyFile, 'r') as myFile:
key = myFile.read()
print(key)
timeNow = int(round(time.time()))
time3Months = timeNow + 86400*90
claims = {
'iss': teamID,
'iat': timeNow,
'exp': time3Months,
'aud': 'https://appleid.apple.com',
'sub': app_id,
}
secret = jwt.encode(claims, key, algorithm='ES256', headers={'kid': kid})
print("secret:")
print(secret)
client_secret = secret.decode("utf-8")
print(client_secret)
Save the clientSecret and appleToken into the local DB at login time with Apple ID.
func authorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization) {
print("didCompleteWithAuthorization : -\(authorization)")
switch authorization.credential {
case let appleIDCredential as ASAuthorizationAppleIDCredential:
// Create an account in your system.
let userIdentifier = appleIDCredential.user
let fullName = appleIDCredential.fullName?.givenName
let email = appleIDCredential.email
guard let appleIDToken = appleIDCredential.identityToken else {
print("Unable to fetch identity token")
return
}
guard let idTokenString = String(data: appleIDToken, encoding: .utf8) else {
return
}
StorageServices.storeInDefaults(object: idTokenString, key: "appleToken")
// Add new code below
if let authorizationCode = appleIDCredential.authorizationCode,
let codeString = String(data: authorizationCode, encoding: .utf8) {
StorageServices.storeInDefaults(object: codeString, key: "clientSecret")
}
default:
break
}
call the apple token revoke api.
func callRevokeTokenAPI() {
guard let clientSecret = StorageServices.readFromDefaults(key: "clientSecret") as? String else {return}
guard let appleToken = StorageServices.readFromDefaults(key: "appleToken") as? String else {return}
let parameters = "client_id=com.oxstren.Actofit-Wear&client_secret=\(clientSecret)&token=\(appleToken)&token_type_hint=access_token"
print(parameters)
let postData = parameters.data(using: .utf8)
var request = URLRequest(url: URL(string: "https://appleid.apple.com/auth/revoke")!,timeoutInterval: Double.infinity)
request.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.httpMethod = "POST"
request.httpBody = postData
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let response = response as? HTTPURLResponse, error == nil else {
print("error", error ?? URLError(.badServerResponse))
return
}
print(response)
guard let data = data else {
print(String(describing: error))
return
}
print(String(data: data, encoding: .utf8)!)
}
task.resume()
} //end function body.
so learning still but i'm getting an Error 401 unauthorised back from the code below. I know that the OAuth header works as it works in postman so i'm assuming there is a problem with the POST request / Auth header? Any ideas?
//set timestamp
Long timestamp = System.currentTimeMillis()/1000;
//set nonce ***** call from main system*************************************************************
String aString = randomAlphaNumeric(11);
// other stuff
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new StringHttpMessageConverter());
HttpHeaders headers = new HttpHeaders();
String url = "aURL";
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
// String auth = Base64.getEncoder().encodeToString(credentials.getBytes());
List<NameValuePair> oauthHeaders = new ArrayList<>(9);
oauthHeaders.add(new BasicNameValuePair("oauth_consumer_key", "aKey"));
oauthHeaders.add(new BasicNameValuePair("oauth_nonce", aString));
oauthHeaders.add(new BasicNameValuePair("oauth_timestamp", String.valueOf(timestamp)));
oauthHeaders.add(new BasicNameValuePair("oauth_signature_method", "HMAC-SHA1"));
oauthHeaders.add(new BasicNameValuePair("oauth_version", "1.0"));
//generate signature
//encode
String encodedURL = encode(oauthHeaders.toString());
System.out.println("encoded URL:" +encodedURL);
//form base string
String baseString = "POST&"+encode(url).toString()+encodedURL;
System.out.println("Base String: "+baseString);
//form signature
byte[] byteHMAC = null;
try {
Mac mac = Mac.getInstance("HmacSHA1");
SecretKeySpec spec;
if (null == secretKey) {
String signingKey = encode(secretKey) + '&';
spec = new SecretKeySpec(signingKey.getBytes(), "HmacSHA1");
} else {
String signingKey = encode(secretKey) + '&' + encode(secretKey);
spec = new SecretKeySpec(signingKey.getBytes(), "HmacSHA1");
}
mac.init(spec);
byteHMAC = mac.doFinal(baseString.getBytes());
} catch (Exception e) {
e.printStackTrace();
}
String signature = new BASE64Encoder().encode(byteHMAC);
System.out.println("oauth signature: "+signature);
//set signature to params
oauthHeaders.add(new BasicNameValuePair("oauth_signature", signature));
String test = "OAuth "+oauthHeaders.toString();
headers.set("Authorization", test);
MultiValueMap<String, String> map = new LinkedMultiValueMap<String, String>();
map.add("Name",name.toString());
map.add("Region",region.toString());
HttpEntity<MultiValueMap<String, String>> requestEntity= new HttpEntity<MultiValueMap<String, String>>(headers, map);
System.out.println(requestEntity);
ResponseEntity<String> response= restTemplate.exchange(url ,HttpMethod.POST, requestEntity, String.class);
System.out.println(response.toString());
HttpStatus status = response.getStatusCode();
status.toString();
if(status.equals("200")){
Notification.show("Employer" + name +" added successfully");
}
else{
Notification.show("Unsuccessful, error: "+status);
}
}
removed the URL and consumer key / signature for obvious reasons.
The following System out prints might help as well:
encoded params:
%5Boauth_consumer_key%3aKey%2C%20oauth_nonce%3DWZU8H1B5JA6%2C%20oauth_timestamp%3D1511621759%2C%20oauth_signature_method%3DHMAC-SHA1%2C%20oauth_version%3D1.0%5D
Base String: POST&https%3A%2F%2Fapi.test.payrun.io%2FEmployer%5Boauth_consumer_key%3aKey%2C%20oauth_nonce%3DWZU8H1B5JA6%2C%20oauth_timestamp%3D1511621759%2C%20oauth_signature_method%3DHMAC-SHA1%2C%20oauth_version%3D1.0%5D
oauth signature: DlRJGSzgRIItzz+LzMbgnIfbOqU=
The value of oauth_signature is wrong. You are using asignature as the value of oauth_signature, but you have to compute the correct value for your request and set it to oauth_signature. If the value of oauth_signature is wrong, the server will reject your request. See "3.4. Signature" in RFC 5849 (The OAuth 1.0 Protocol) for details.
For anyone who wants to make this work then please see below for a complete OAuth Generator example :):
public class oAuthGenerator {
private String httpMethod;
private String params;
private String url;
//Required for percent encoding
private static final String ENC = "ASCII";
//Required for nonce
private static final String ALPHA_NUMERIC_STRING = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz";
//As provided by Payrun.io
private static final String secretKey = "aSecretKey";
//As provided by Payrun.io
private static final String consumerKey ="aConsumerKey";
private List veriList;
//Constructor for setting signature base string values.
//#Param url needs to be percent encoded
//#Param params needs to be percent encoded, this is done #Method generateOAuth()
public oAuthGenerator(String httpMethod,String url )throws Exception {
veriList= new ArrayList<String>();
veriList.add("POST");
veriList.add("GET");
veriList.add("PUT");
veriList.add("DELETE");
if (veriList.contains(httpMethod)){
this.httpMethod = httpMethod+"&";}
this.url = URLEncoder.encode(url,ENC)+"&";
}
//A method used to generate the OAuth Authorization header
//#Method randomAlphaNumeric() calls internal method using instance variable ALPHA_NUMERIC_STRING
//#Method getSignature() returns String HMACSHA1 > Base64 encoded value of httpMethod,url,params
public String generateOAuth()throws Exception{
//Set timestamp as seconds from 01-01-1970
Timestamp timestamp = new Timestamp(System.currentTimeMillis()/1000);
Long aTimestamp = timestamp.getTime();
//Set nonce which is a 10 digit random, non repeating alpha-numeric value
String aNonce = randomAlphaNumeric(10);
//Normalize and form param string
String normalizedParams = "oauth_consumer_key="+consumerKey+"&"+"oauth_nonce="+aNonce+"&"+"oauth_signature_method="+"HMAC-SHA1"+"&"+"oauth_timestamp="+ aTimestamp.toString()+"&"+"oauth_version="+"1.0";
//Percent encoded params
params = URLEncoder.encode(normalizedParams,ENC);
//Set signature variable
String signature = getSignature();
//place into required format
String oAuthResult = "OAuth "+"oauth_version="+"\"1.0\""+","+"oauth_consumer_key="+"\"" + consumerKey + "\""+","+"oauth_signature_method="+"\"HMAC-SHA1\""+","+"oauth_timestamp="+"\""+aTimestamp+"\""+","+"oauth_nonce="+"\""+aNonce+"\""+","+"oauth_signature="+"\""+signature+"\"";
return oAuthResult;
}
// A method designed to return a hashed and base64 encoded value.
//#Param aString holds HMAC-SHA1 and Base 64 encoded value of variables httpMethod,url,params
//#Param result holds percent encoded value of aString
private String getSignature()
throws Exception {
//form base string
StringBuilder base = new StringBuilder();
base.append(httpMethod);
base.append(url);
base.append(params);
//Set SecretKey of variable secretKey using HMAC-SHA1 algorithm
SecretKey signingKey = new SecretKeySpec(secretKey.getBytes(), "HmacSHA1");
// Get an hmac_sha1 Mac instance and initialize with the signing key
Mac mac = Mac.getInstance("HmacSHA1");
mac.init(signingKey);
// Compute the hmac on input data bytes, then encode to Base64
String aString = Base64.getEncoder().encodeToString(mac.doFinal(base.toString().getBytes(ENC))).trim();
//Percent encoded the Base64 value
String result = URLEncoder.encode(aString, ENC);
return new String(result);
}
//Required for nonce, returns a random alpha numeric value by using variable ALPHA_NUMERIC_STRING
private static String randomAlphaNumeric(int count) {
StringBuilder builder = new StringBuilder();
while (count-- != 0) {
int character = (int)(Math.random()*ALPHA_NUMERIC_STRING.length());
builder.append(ALPHA_NUMERIC_STRING.charAt(character));
}
return builder.toString();
}
}
I am trying to add multiple header. But failed miserably so far. I had tried lots of code tweaking but failed. Can someone help me fix the code or at least tell me what's wrong ?
Header mapping code:
Map<String, String> headers = new HashMap<String, String>();
headers.put("authorization", authToken);
headers.put("API-Version", apiVersion);
headers.put("Content-Type", MediaType.APPLICATION_JSON);
actual calling code:
String serviceUrl = serviceHostUrl;
Client client = Client.create();
WebResource webResource = client.resource(serviceUrl).path(path);
WebResource.Builder builder = webResource.getRequestBuilder();
if(headers != null && !headers.isEmpty()) {
for(Map.Entry<String, String> entry : headers.entrySet()) {
builder.header(entry.getKey(), entry.getValue());
}
}
ClientResponse response = builder.post(ClientResponse.class, input);
UPDATE
if in second snippet I use below code instead of setting headers in loop, it works fine. That's really weird.
builder.header("authorization", "Basic SDFSFSDFSDFSDFSDFSDFSDF");
builder.header("API-Version", "5.2");
builder.header("Content-Type", MediaType.APPLICATION_JSON);
I think the issue here is, type of MAP that you are trying to access.
Map<String, Object> headers = new HashMap<String, Object>();
The WebSource builder accepts header(String,Object). So Try with changing the map type.
The header method does change the builder object. It creates a new object and the existing builder is not affected.
for(Map.Entry<String, String> entry : headers.entrySet()) {
builder = builder.header(entry.getKey(), entry.getValue());
}
Basic auth is like: Authorization = "Authorization" ":" credentials
an example
byte[] loginBytes = ("1" + ":" + "1").getBytes();
StringBuilder authString = new StringBuilder().append("Basic ")
.append(Base64.encodeToString(loginBytes, Base64.NO_WRAP));
_headers.put("Authorization", authString );
I am not an expert with REST APIs and I am running into issues when trying to makes calls to the Duo 2 factor authentication API: https://www.duosecurity.com/docs/authapi#api-details
It looks really straight forward, but I think I am missing something, I have been working on this for 2 days without success.
I am using Jersey, which gives me the following error:
java.lang.IllegalArgumentException: Illegal character(s) in message header value: Basic RElGUE1MSVQyMU40OUhORURL[...]YTYzOQ==
(I have shortened the key in the above line)
The API uses HTTP Basic Authentication to authenticate requests.
I did follow the instructions in the doc for the authentication. I did generate the HTTP Password as an HMAC signature of the request. I also did build the signature as explained in the doc, by first building an ASCII string from my request, then by concatenating the components with line feeds and computing the HMAC-SHA1 of the canonical representation, then encoding username:hmac in Base64.
I think I might be misunderstanding something on the encoding part or not doing something properly.
Here is part of my code:
public Enroll enroll(String username){
HashMap<String, String> formData = new HashMap<String, String>();
formData.put("username", username);
String date = generateDate();
String signature = constructSignature("POST", "/auth/v2/enroll", formData);
String authValue = generateAuthValue(secretKey, signature);
Enroll response = service.path("auth").path("v2").path("enroll").header("Date", date)
.header("Content-Type", "application/x-www-form-urlencoded")
.header("Authorization", authValue).type(MediaType.APPLICATION_FORM_URLENCODED_TYPE)
.accept(MediaType.APPLICATION_JSON_TYPE).post(Enroll.class, formData);
return response;
}
public String generateAuthValue(String secretKey, String signature){
String hmacValue = calcShaHash(signature, integrationKey, secretKey);
return hmacValue;
}
private String constructSignature(String method, String path, HashMap<String, String> params){
String date = generateDate();
String lineFeed = "\n";
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(date);
stringBuilder.append(lineFeed);
stringBuilder.append(method);
stringBuilder.append(lineFeed);
stringBuilder.append(apiHostName);
stringBuilder.append(lineFeed);
stringBuilder.append(path);
stringBuilder.append(lineFeed);
stringBuilder = urlEncodeParameters(params, stringBuilder);
return stringBuilder.toString();
}
private StringBuilder urlEncodeParameters(HashMap<String, String> params, StringBuilder stringBuilder){
try{
for (Map.Entry<String, String> entry : params.entrySet()){
stringBuilder.append(URLEncoder.encode(entry.getKey().toString(), "UTF-8"));
stringBuilder.append("=");
stringBuilder.append(URLEncoder.encode(entry.getValue().toString(), "UTF-8"));
stringBuilder.append("\n");
//signature.concat(encoded);
}
}catch (UnsupportedEncodingException e){
e.printStackTrace();
}
return stringBuilder;
}
public static String calcShaHash(String data, String integrationKey, String secretKey){
String HMAC_SHA1_ALGORITHM = "HmacSHA1";
StringBuilder result = new StringBuilder();
try{
Key signingKey = new SecretKeySpec(secretKey.getBytes("UTF-8"), HMAC_SHA1_ALGORITHM);
Mac mac = Mac.getInstance(HMAC_SHA1_ALGORITHM);
mac.init(signingKey);
byte[] rawHmac = mac.doFinal(data.getBytes("UTF-8"));
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(integrationKey);
stringBuilder.append(":");
stringBuilder.append(Hex.encodeHexString(rawHmac).toString());
byte[] byteAuthorizationValue = stringBuilder.toString().getBytes("UTF-8");
result.append("Basic ");
result.append(Base64.encode(byteAuthorizationValue).toString());
}catch (Exception e){
e.printStackTrace();
}
return result.toString();
}
private String generateDate(){
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss ZZZZ");
String formattedDate = sdf.format(date);
return formattedDate;
}
Make sure that your requestXML or any header value does not have any illegal characters and replace it like...
aXmlRequest=aXmlRequest.replaceAll("\n", "");
I guess it is the same problem I am facing at the moment.
The illegal character is a new-line-character at the end of the auth header.
Take a look at Java: fetch URL with HTTPBasic Authentication for more information.
I use the org.apache.commons.codec.binary.Base64 class from the commons-codec library to get Base64 encryption. I'm not sure but maybe it solves your problem.
Best regards,
Felix