Google Cloud Storage - JAVA REST API - Getting SignatureDoesNotMatch - google-cloud-storage

I am using jersey-client to make REST Call . I am getting SignatureDoesNotMatch error in response.
I was trying to List down Bucket names using GET Service , also tried to list Bucket object using GET Bucket method.
here is my sample code.
Any hint or solution ?
public class restSample {
private static final String HMAC_SHA1_ALGORITHM = "HmacSHA1";
private static final String PROJECT_ID = "10XXXXXXXX478";
public static String Base64Encoding()
throws java.security.SignatureException, UnsupportedEncodingException {
String access_id = "GOOGBAXXXXXXXXXXBI";
String secret_key = URLEncoder.encode("pWTXXXXXXXXXXXXXXXRo85T+XXXXXXXXX3O","UTF-8");
String bucket = "bucket_name";
String version_header = "x-goog-api-version:1";
String project_header = "x-goog-project-id:"+PROJECT_ID;
String canonicalizedResources = "/"+bucket+"/";
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.MINUTE, 30);
long expiration = calendar.getTimeInMillis();
String stringToSign = URLEncoder.encode("GET\n\n\n"+expiration+"\n"+version_header+"\n"+project_header+"\n"+canonicalizedResources,"UTF-8");
//String stringToSign = URLEncoder.encode("GET\n\n\n"+getdate()+"\n"+version_header+"\n"+project_header+"\n"+canonicalizedResources,"UTF-8");
String authSignature="";
try {
SecretKeySpec signingKey = new SecretKeySpec(secret_key.getBytes(),HMAC_SHA1_ALGORITHM);
Mac mac = Mac.getInstance(HMAC_SHA1_ALGORITHM);
mac.init(signingKey);
// compute the hmac on input data bytes
byte[] rawHmac = mac.doFinal(stringToSign.getBytes("UTF-8"));
// base64-encode the hmac
authSignature = new String(Base64.encode(rawHmac));
} catch (Exception e) {
throw new SignatureException("Failed to generate HMAC : " + e.getMessage());
}
authSignature = (access_id +":"+ authSignature);
return authSignature;
}
public static void main(String[] args) {
ClientConfig config = new DefaultClientConfig();
Client client = Client.create(config);
String authSignature = null;
try {
authSignature = "GOOG1 "+ Base64Encoding();
} catch (SignatureException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
WebResource service = client.resource(getBaseURI());
ClientResponse response = service.accept(MediaType.APPLICATION_XML)
.header("Authorization",authSignature)
.header("Date", getdate())
.header("Content-Length", "0")
.header("x-goog-api-version", "1")
.header("x-goog-project-id", PROJECT_ID)
.get(ClientResponse.class);
System.out.println(response.getClientResponseStatus().getFamily());
System.out.println("response1 :: " + response.getEntity(String.class));
}
private static URI getBaseURI() {
String url = "https://bucket_name.storage.googleapis.com";
return UriBuilder.fromUri(url).build();
}
private static String getdate(){
SimpleDateFormat format = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z ", new Locale("US"));
Calendar cal = Calendar.getInstance(new SimpleTimeZone(0, "GMT"));
format.setCalendar(cal);
return format.format(new Date());
}
}
Thanks!

Make sure the string you are signing matches the expected string to sign. Google cloud storage returns the expected string to sign in the HTTP response if authentication fails.
In your particular example it looks like you are adding both the version_header and project_header into the string to sign. These are not in the list of CanonicalHeaders nor CanonicalExtensionHeaders, so you are signing a different string than the server.
You can review the list here: https://developers.google.com/storage/docs/reference/v1/developer-guidev1#authentication

Related

Get Exception in thread "main" org.zaproxy.clientapi.core.ClientApiException: Does Not Exist on running form ans script authentication using zap api

public class FormAuth {
private static final String ZAP_ADDRESS = "localhost";
private static final int ZAP_PORT = 8080;
private static final String ZAP_API_KEY = null;
private static final String contextId = "1";
private static final String contextName = "Default Context";
private static final String target = "http://localhost:8090/bodgeit";
private static void setIncludeAndExcludeInContext(ClientApi clientApi) throws UnsupportedEncodingException, ClientApiException {
String includeInContext = "http://localhost:8090/bodgeit.*";
String excludeInContext = "http://localhost:8090/bodgeit/logout.jsp";
clientApi.context.includeInContext(contextName, includeInContext);
clientApi.context.excludeFromContext(contextName, excludeInContext);
}
private static void setLoggedInIndicator(ClientApi clientApi) throws UnsupportedEncodingException, ClientApiException {
// Prepare values to set, with the logged in indicator as a regex matching the logout link
String loggedInIndicator = "Logout";
// Actually set the logged in indicator
clientApi.authentication.setLoggedInIndicator(contextId, java.util.regex.Pattern.quote(loggedInIndicator));
// Check out the logged in indicator that is set
System.out.println("Configured logged in indicator regex: "
+ ((ApiResponseElement) clientApi.authentication.getLoggedInIndicator(contextId)).getValue());
}
private static void setFormBasedAuthenticationForBodgeit(ClientApi clientApi) throws ClientApiException,
UnsupportedEncodingException {
// Setup the authentication method
String loginUrl = "http://localhost:8090/bodgeit/login.jsp";
String loginRequestData = "username={%username%}&password={%password%}";
// Prepare the configuration in a format similar to how URL parameters are formed. This
// means that any value we add for the configuration values has to be URL encoded.
StringBuilder formBasedConfig = new StringBuilder();
formBasedConfig.append("loginUrl=").append(URLEncoder.encode(loginUrl, "UTF-8"));
formBasedConfig.append("&loginRequestData=").append(URLEncoder.encode(loginRequestData, "UTF-8"));
System.out.println("Setting form based authentication configuration as: "
+ formBasedConfig.toString());
clientApi.authentication.setAuthenticationMethod(contextId, "formBasedAuthentication",
formBasedConfig.toString());
// Check if everything is set up ok
System.out
.println("Authentication config: " + clientApi.authentication.getAuthenticationMethod(contextId).toString(0));
}
private static String setUserAuthConfigForBodgeit(ClientApi clientApi) throws ClientApiException, UnsupportedEncodingException {
// Prepare info
String user = "Test User";
String username = "test#example.com";
String password = "weakPassword";
// Make sure we have at least one user
String userId = extractUserId(clientApi.users.newUser(contextId, user));
// Prepare the configuration in a format similar to how URL parameters are formed. This
// means that any value we add for the configuration values has to be URL encoded.
StringBuilder userAuthConfig = new StringBuilder();
userAuthConfig.append("username=").append(URLEncoder.encode(username, "UTF-8"));
userAuthConfig.append("&password=").append(URLEncoder.encode(password, "UTF-8"));
System.out.println("Setting user authentication configuration as: " + userAuthConfig.toString());
clientApi.users.setAuthenticationCredentials(contextId, userId, userAuthConfig.toString());
clientApi.users.setUserEnabled(contextId, userId, "true");
clientApi.forcedUser.setForcedUser(contextId, userId);
clientApi.forcedUser.setForcedUserModeEnabled(true);
// Check if everything is set up ok
System.out.println("Authentication config: " + clientApi.users.getUserById(contextId, userId).toString(0));
return userId;
}
private static String extractUserId(ApiResponse response) {
return ((ApiResponseElement) response).getValue();
}
private static void scanAsUser(ClientApi clientApi, String userId) throws ClientApiException {
clientApi.spider.scanAsUser(contextId, userId, target, null, "true", null);
}
/**
* The main method.
*
* #param args the arguments
* #throws ClientApiException
* #throws UnsupportedEncodingException
*/
public static void main(String[] args) throws ClientApiException, UnsupportedEncodingException {
ClientApi clientApi = new ClientApi(ZAP_ADDRESS, ZAP_PORT, ZAP_API_KEY);
setIncludeAndExcludeInContext(clientApi);
setFormBasedAuthenticationForBodgeit(clientApi);
setLoggedInIndicator(clientApi);
String userId = setUserAuthConfigForBodgeit(clientApi);
scanAsUser(clientApi, userId);
}
}
=========================================================================================
/usr/lib/jvm/java-1.11.0-openjdk-amd64/bin/java -javaagent:/snap/intellij-idea-ultimate/319/lib/idea_rt.jar=43425:/snap/intellij-idea-ultimate/319/bin -Dfile.encoding=UTF-8 -classpath /home/arpit/IdeaProjects/maven-zap-demo/target/classes:/home/arpit/Downloads/zap-clientapi-1.9.0.jar ScriptAuth
Exception in thread "main" org.zaproxy.clientapi.core.ClientApiException: Does Not Exist
at org.zaproxy.clientapi.core.ApiResponseFactory.getResponse(ApiResponseFactory.java:50)
at org.zaproxy.clientapi.core.ClientApi.callApi(ClientApi.java:351)
at org.zaproxy.clientapi.gen.deprecated.ScriptDeprecated.load(ScriptDeprecated.java:146)
at ScriptAuth.uploadScript(ScriptAuth.java:76)
at ScriptAuth.main(ScriptAuth.java:93)
The recommended way to automate authentiation in ZAP is to configure and test it in the desktop, then export the context and import that via the API. If the authentication uses scripts then these will need to be registered with ZAP first.

Created OAuth bearer token generated with jwt token is invalid for REST calls

I am new to DocuSign and the REST-API. I created a developer account and added a new "Apps and Keys" entry for my application (Authentication = Implicit Grant and RSA key pairs). The keys were stored in two seperate files.
I activated the Keys using the following URL:
http://account-d.docusign.com/oauth/auth?response_type=code&scope=signature%20impersonation&client_id=_the_integration_key&redirect_uri=http://localhost
I am trying to write a JAVA application without spring security framework (or any other framework).
To read the key files I used and modified (a little bit) the functions from the DocuSign examples.
private static RSAPublicKey readPublicKeyFromFile(String filepath, String algorithm) throws IOException {
File pemFile = new File(filepath);
if (!pemFile.isFile() || !pemFile.exists()) {
throw new FileNotFoundException(String.format("The file '%s' doesn't exist.", pemFile.getAbsolutePath()));
}
PemReader reader = new PemReader(new FileReader(pemFile));
try {
PemObject pemObject = reader.readPemObject();
byte[] bytes = pemObject.getContent();
RSAPublicKey publicKey = null;
try {
KeyFactory kf = KeyFactory.getInstance(algorithm);
EncodedKeySpec keySpec = new X509EncodedKeySpec(bytes);
publicKey = (RSAPublicKey) kf.generatePublic(keySpec);
} catch (NoSuchAlgorithmException e) {
System.out.println("Could not reconstruct the public key, the given algorithm could not be found.");
} catch (InvalidKeySpecException e) {
System.out.println("Could not reconstruct the public key");
}
return publicKey;
} finally {
reader.close();
}
}
private static RSAPrivateKey readPrivateKeyFromFile(String filepath, String algorithm) throws IOException {
File pemFile = new File(filepath);
if (!pemFile.isFile() || !pemFile.exists()) {
throw new FileNotFoundException(String.format("The file '%s' doesn't exist.", pemFile.getAbsolutePath()));
}
PemReader reader = new PemReader(new FileReader(pemFile));
try {
PemObject pemObject = reader.readPemObject();
byte[] bytes = pemObject.getContent();
RSAPrivateKey privateKey = null;
try {
Security.addProvider(new BouncyCastleProvider());
KeyFactory kf = KeyFactory.getInstance(algorithm, "BC");
EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(bytes);
privateKey = (RSAPrivateKey) kf.generatePrivate(keySpec);
} catch (NoSuchAlgorithmException e) {
System.out.println("Could not reconstruct the private key, the given algorithm could not be found.");
} catch (InvalidKeySpecException e) {
System.out.println("Could not reconstruct the private key");
} catch (NoSuchProviderException e) {
System.out.println("Could not reconstruct the private key, invalid provider.");
}
return privateKey;
} finally {
reader.close();
}
}
private static RSAPrivateKey readPrivateKeyFromByteArray(byte[] privateKeyBytes, String algorithm) throws IOException {
PemReader reader = new PemReader(new StringReader(new String(privateKeyBytes)));
try {
PemObject pemObject = reader.readPemObject();
byte[] bytes = pemObject.getContent();
RSAPrivateKey privateKey = null;
try {
Security.addProvider(new BouncyCastleProvider());
KeyFactory kf = KeyFactory.getInstance(algorithm, "BC");
EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(bytes);
privateKey = (RSAPrivateKey) kf.generatePrivate(keySpec);
} catch (NoSuchAlgorithmException e) {
System.out.println("Could not reconstruct the private key, the given algorithm could not be found.");
} catch (InvalidKeySpecException e) {
System.out.println("Could not reconstruct the private key");
} catch (NoSuchProviderException e) {
System.out.println("Could not reconstruct the private key, invalid provider.");
}
return privateKey;
} finally {
reader.close();
}
}
To get the JWT token I used the following function:
public static String generateJWTAssertion(String publicKeyFilename, String privateKeyFilename, String oAuthBasePath, String clientId, String userId, long expiresIn) throws JWTCreationException, IOException {
String token = null;
if (expiresIn <= 0L) {
throw new IllegalArgumentException("expiresIn should be a non-negative value");
}
if (publicKeyFilename == null || "".equals(publicKeyFilename) || privateKeyFilename == null || "".equals(privateKeyFilename) || oAuthBasePath == null || "".equals(oAuthBasePath) || clientId == null || "".equals(clientId)) {
throw new IllegalArgumentException("One of the arguments is null or empty");
}
try {
RSAPublicKey publicKey = readPublicKeyFromFile(publicKeyFilename, "RSA");
RSAPrivateKey privateKey = readPrivateKeyFromFile(privateKeyFilename, "RSA");
Algorithm algorithm = Algorithm.RSA256(publicKey, privateKey);
long now = System.currentTimeMillis();
token = JWT.create()
.withIssuer(clientId) // integration key
.withSubject(userId) // null
.withAudience(oAuthBasePath) // account-d.docusign.com
.withNotBefore(new Date(now))
.withExpiresAt(new Date(now + expiresIn * 1000))
.withClaim("scope", "signature impersonation")
.sign(algorithm);
} catch (JWTCreationException e){
throw e;
} catch (IOException e) {
throw e;
}
return token;
}
I checked the generated token on https://jwt.io/ and the content looks fine.
To get the bearer token I use the following code:
public Boolean getBearer(long expiresIn) throws IOException {
String jwtToken = JwtUtils.generateJWTAssertion(
RESOURCES_DIR + "public.key",
RESOURCES_DIR + "private.key",
oAuthBasePath,
integrationKey,
null,
expiresIn
);
OkHttpClient client = new OkHttpClient().newBuilder()
.build();
MediaType mediaType = MediaType.parse("text/plain");
MediaType JSON = MediaType.parse("application/json; charset=utf-8");
RequestBody body = new MultipartBody.Builder().setType(MultipartBody.FORM)
.addFormDataPart("grant_type", "urn:ietf:params:oauth:grant-type:jwt-bearer")
.addFormDataPart("assertion", jwtToken)
.build();
Request request = new Request.Builder()
.url("https://" + oAuthBasePath + "/oauth/token") // https://account-d.docusign.com/oauth/token
.method("POST", body)
.build();
Response response = client.newCall(request).execute();
int responseCode = response.code();
String responseText = response.body().string();
Gson gson = new Gson();
OAuthResponse oAuthResponse = gson.fromJson(responseText, OAuthResponse.class);
if (responseCode >= 200 && responseCode <= 299) {
bearerToken = oAuthResponse.getAccess_token();
return true;
}
System.out.println("Errorcode: " + oAuthResponse.getError());
System.out.println("Error: " + oAuthResponse.getError_description());
return false;
}
I get the bearer token and want to use it for the following REST calls.
For example:
public void getUsers () throws IOException {
OkHttpClient client = new OkHttpClient().newBuilder()
.build();
Request request = new Request.Builder()
.url(getRestBaseUrl() +"/users") // https://demo.docusign.net/restapi/v2.1/accounts/_API_account_id/users
.method("GET", null)
.addHeader("Accept", "application/json")
.addHeader("Authorization", "Bearer " + bearerToken)
.build();
Response response = client.newCall(request).execute();
String responseText = response.body().string();
System.out.println(responseText);
}
But instead of a JSON structure with the users of my developer account, I got the following response:
{"errorCode":"AUTHORIZATION_INVALID_TOKEN","message":"The access token provided is expired, revoked or malformed. Authentication for System Application failed."}
When I use the API explorer and the bearer token, I can use it for authentication (it is shown as valid), but the REST call for "users" get the same error response.
So I used the API explorer for login and the REST call works.
I used the bearer token from the API explorer and used it (as fixed entered string value) as bearer token. And the JAVA REST calls works.
So, there must be an error in generating / requesting the JWT token or bearer token.
Any idea what's wrong?
Regards,
Rainer
I found the reason.
The API username was missing.
String jwtToken = JwtUtils.generateJWTAssertion(
RESOURCES_DIR + "public.key",
RESOURCES_DIR + "private.key",
oAuthBasePath,
integrationKey,
"_here_the_API_username",
expiresIn
);
After adding the username I could use the API.

iOS JWE AES GCM 256

I am trying to implement JWE token in Swift using JOSESwift (modified to support AES-GCM 256) and CryptoSwift(need to support iOS 11+). I am able to encrypt and decrypt using public/private key pair. But when the same JWE token passed on to Java (server-side program) it's not able to decrypt. Vice e versa is also not working. Need help, can share my github project
https://github.com/sreekanthps/VAMDemoJava.git - Java project https://github.com/sreekanthps/VMADemo.git - iOS project https://github.com/sreekanthps/JOSESwift-AES256GCM.git - modified JOSESwift project
Nimbus
Exception in thread "main" com.nimbusds.jose.JOSEException: AES/GCM/NoPadding decryption failed: Tag mismatch!
at com.nimbusds.jose.crypto.impl.AESGCM.decrypt(AESGCM.java:301)
at com.nimbusds.jose.crypto.impl.ContentCryptoProvider.decrypt(ContentCryptoProvider.java:279)
at com.nimbusds.jose.crypto.RSADecrypter.decrypt(RSADecrypter.java:285)
at com.nimbusds.jose.JWEObject.decrypt(JWEObject.java:415)
at me.txedo.security.Main.numbusJWe(Main.java:127)
at me.txedo.security.Main.main(Main.java:52)
Jose4j
Exception in thread "main" org.jose4j.lang.JoseException: javax.crypto.AEADBadTagException: Tag mismatch!
at org.jose4j.jwe.SimpleAeadCipher.decrypt(SimpleAeadCipher.java:114)
at org.jose4j.jwe.SimpleAeadCipher.decrypt(SimpleAeadCipher.java:101)
at org.jose4j.jwe.AesGcmContentEncryptionAlgorithm.decrypt(AesGcmContentEncryptionAlgorithm.java:79)
at org.jose4j.jwe.JsonWebEncryption.decrypt(JsonWebEncryption.java:249)
at org.jose4j.jwe.JsonWebEncryption.getPlaintextBytes(JsonWebEncryption.java:85)
at org.jose4j.jwe.JsonWebEncryption.getPlaintextString(JsonWebEncryption.java:78)
at org.jose4j.jwe.JsonWebEncryption.getPayload(JsonWebEncryption.java:93)
at me.txedo.security.Main.jose4JDeryption(Main.java:166)
at me.txedo.security.Main.main(Main.java:55)
Swift code
keyData = try! randomData(ofLength: 32)
ivData = try! randomData(ofLength: 16)
let message = "Summer ⛱, Sun ☀️, Cactus 🌵".data(using: .utf8)!
let header = JWEHeader(keyManagementAlgorithm: .RSAOAEP256, contentEncryptionAlgorithm: .AES256GCM)
let payload = Payload(message)
let publickey = RSAKeyGenerator.shared.getPublicKey()
let privateKey = RSAKeyGenerator.shared.getPrivateKey()
let encrypter = Encrypter(keyManagementAlgorithm: .RSAOAEP256, contentEncryptionAlgorithm: .AES256GCM, encryptionKey: publickey!)!
if let jwe = try? JWE(header: header, payload: payload, encrypter: encrypter) {
jwtString = jwe.compactSerializedString
print("jwtString : \(jwtString!)")
}
do {
let jwe = try JWE(compactSerialization: jwtString!)
let decrypter = Decrypter(keyManagementAlgorithm: .RSAOAEP256, contentEncryptionAlgorithm: .AES256GCM, decryptionKey: privateKey!)!
let payload = try jwe.decrypt(using: decrypter)
let message = String(data: payload.data(), encoding: .utf8)!
print(message) // Summer ⛱, Sun ☀️, Cactus 🌵
}catch {
print("Decryption error :\(error.localizedDescription)")
}
Java Code
protected final static Logger LOGGER = Logger.getLogger(Main.class);
public final static String RESOURCES_DIR = "/Users/swesree/Desktop/KH802/CERTS/";
public static void main(String[] args) throws FileNotFoundException,
IOException, NoSuchAlgorithmException, NoSuchProviderException, ParseException, JOSEException, JoseException {
Security.addProvider(new BouncyCastleProvider());
LOGGER.info("BouncyCastle provider added.");
KeyFactory factory = KeyFactory.getInstance("RSA", "BC");
try {
PrivateKey priv = generatePrivateKey(factory, RESOURCES_DIR + "vmaprivate.pem");
LOGGER.info(String.format("Instantiated private key: %s", priv));
PublicKey pub = generatePublicKey(factory, RESOURCES_DIR + "vmapublic.pem");
LOGGER.info(String.format("Instantiated public key: %s", pub));
//numbusJWe(pub,priv);
String jweString = jose4JEcnryption(pub);
jose4JDeryption(priv,jweString);
} catch (InvalidKeySpecException e) {
e.printStackTrace();
}
}
private static PrivateKey generatePrivateKey(KeyFactory factory, String filename)
throws InvalidKeySpecException, FileNotFoundException, IOException {
PemFile pemFile = new PemFile(filename);
byte[] content = pemFile.getPemObject().getContent();
PKCS8EncodedKeySpec privKeySpec = new PKCS8EncodedKeySpec(content);
return factory.generatePrivate(privKeySpec);
}
private static PublicKey generatePublicKey(KeyFactory factory, String filename)
throws InvalidKeySpecException, FileNotFoundException, IOException {
PemFile pemFile = new PemFile(filename);
byte[] content = pemFile.getPemObject().getContent();
X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(content);
return factory.generatePublic(pubKeySpec);
}
private static void numbusJWe(PublicKey publicKey, PrivateKey privKey) throws ParseException, JOSEException {
Date now = new Date();
JWTClaimsSet jwtClaims = new JWTClaimsSet.Builder()
.issuer("https://openid.net")
.subject("alice")
.audience(Arrays.asList("https://app-one.com", "https://app-two.com"))
.expirationTime(new Date(now.getTime() + 1000*60*10)) // expires in 10 minutes
.notBeforeTime(now)
.issueTime(now)
.jwtID(UUID.randomUUID().toString())
.build();
System.out.println(jwtClaims.toJSONObject());
// Request JWT encrypted with RSA-OAEP-256 and 128-bit AES/GCM
JWEHeader header = new JWEHeader(JWEAlgorithm.RSA_OAEP_256, EncryptionMethod.A256GCM);
// Create the encrypted JWT object
EncryptedJWT jwt = new EncryptedJWT(header, jwtClaims);
// Create an encrypter with the specified public RSA key
RSAEncrypter encrypter = new RSAEncrypter((RSAPublicKey) publicKey);
// Do the actual encryption
jwt.encrypt(encrypter);
// Serialise to JWT compact form
String jwtString = jwt.serialize();
System.out.println("jwtString : "+jwtString);
//
//
// Parse back
//String jwtStringNew = "eyJlbmMiOiJBMjU2R0NNIiwiYWxnIjoiUlNBLU9BRVAtMjU2In0.hJ905rCCsW0u07cCleTh_eYKAyDP7ZHNnRA50qDWXo7seygePzIkr37ZCeaW2hmZ-c6v_c7Yp3Y0kzE5OE0h93J09XAtYfwZk3zZVKXH8hd6fWjeY7ZgB8I4CpQaa9BX-Zp9bBznXHh5WqpckkMAXZVT-wiLNVqQDpyg8Jifi5tuw4SjT4irRrFYF5LfSDLU4EigKKC3Rn1IOlwEKhHuvqLFuCbqgXVh_Ps75P9_wXr3XoKSwEDf5zbOh42cPlenKfG0TQpeEhKamEbmpuRnOZYRHmOQ0d6KTI7t8xxRQ0g3nF0AJGQKwnbZDgZPli8v3dI8XZY9rca03rG8aQpCag.JFWISQTeuw2euVfT.5ekMlQk5tkPFLdUnZIh-GMfFGS36UPKAd_obtu-YCy_vv_iuNPVbxZyzjJFRnK2-G8Cf3UuKvpNusyjpd_AfIvoxg7fqCr95CZ8IulBGo1SddvcXx-kCsCNPawK97pN7qclHc6oqrIpK4CjUR0msJtgNbdTrFI0VOw1dLXoz_jFJ13xO1LQiXkxdJltD6qpEfE3x1UyNFpDHudplur7v6cd9WOXNFlQ6zQYfn-9ZHOMGoGFcQAB9u9crCkoyIX4vifNrJA.zD8126ElxZvp-RODUr5qSg";
String jwtStringNew = "eyJlbmMiOiJBMjU2R0NNIiwiYWxnIjoiUlNBLU9BRVAtMjU2In0.wDiB-oEawb6cBHUyHT-_LVtRwaA7bwL8qwoqXGYayXae6EFr6wKIP2M5woq9HSGWRFH48JIyNS6V_K3MdXfh9oqjVd3djBeUKtcP6b-2jWjFxLL-WOgZpHmSMpWhOB55ogKQRumo0YYn4HMd8JrQ48uYGa7NoWOxMIBajKNu4utkOW-1q-ccbN4_6mds90brEJDnlbcHyo22sjufiXeKhN8_JaN6uqx3qet08ouhEEOaFhssj7nyP3ynz75rT17iw_VAoS91JP6lb-Q4T4ZsA_9_ibZUZn4vkk1mWU0Kul2Hp0z5GXw_ZPNi7IsTv0D4xvDnWmwTUb3ekdj0cCYmMg.e0w_dONIFxka8bXU.bEAl8JYqj-4xSlC1i4xXSbdMqBz61TuKUHdYq46L2_vxTpTjh04o5juH4eDbs6cfEgGy.44dOKOY7h-Hg27OnHxIBsg";
EncryptedJWT jwt1= EncryptedJWT.parse(jwtStringNew);
// Create a decrypter with the specified private RSA key
RSADecrypter decrypter = new RSADecrypter(privKey);
// Decrypt
jwt1.decrypt(decrypter);
System.out.println(jwt1.getHeader());
System.out.println("numbusJWe::: "+jwt1.getPayload());
// TODO Auto-generated method stub
}
private static String jose4JEcnryption(PublicKey key) throws JoseException {
JsonWebEncryption jwe = new JsonWebEncryption();
jwe.setPayload("Hello World!");
jwe.setAlgorithmHeaderValue(KeyManagementAlgorithmIdentifiers.RSA_OAEP_256);
jwe.setEncryptionMethodHeaderParameter(ContentEncryptionAlgorithmIdentifiers.AES_256_GCM);
jwe.setKey(key);
String serializedJwe = jwe.getCompactSerialization();
System.out.println("Serialized Encrypted JWE: " + serializedJwe);
return serializedJwe;
}
private static void jose4JDeryption(PrivateKey key, String jweToken) throws JoseException {
String jwtStringNew1 = "eyJlbmMiOiJBMjU2R0NNIiwiYWxnIjoiUlNBLU9BRVAtMjU2In0.wDiB-oEawb6cBHUyHT-_LVtRwaA7bwL8qwoqXGYayXae6EFr6wKIP2M5woq9HSGWRFH48JIyNS6V_K3MdXfh9oqjVd3djBeUKtcP6b-2jWjFxLL-WOgZpHmSMpWhOB55ogKQRumo0YYn4HMd8JrQ48uYGa7NoWOxMIBajKNu4utkOW-1q-ccbN4_6mds90brEJDnlbcHyo22sjufiXeKhN8_JaN6uqx3qet08ouhEEOaFhssj7nyP3ynz75rT17iw_VAoS91JP6lb-Q4T4ZsA_9_ibZUZn4vkk1mWU0Kul2Hp0z5GXw_ZPNi7IsTv0D4xvDnWmwTUb3ekdj0cCYmMg.e0w_dONIFxka8bXU.bEAl8JYqj-4xSlC1i4xXSbdMqBz61TuKUHdYq46L2_vxTpTjh04o5juH4eDbs6cfEgGy.44dOKOY7h-Hg27OnHxIBsg";
JsonWebEncryption jwe = new JsonWebEncryption();
jwe.setAlgorithmConstraints(new AlgorithmConstraints(ConstraintType.PERMIT,
KeyManagementAlgorithmIdentifiers.RSA_OAEP_256));
jwe.setContentEncryptionAlgorithmConstraints(new AlgorithmConstraints(ConstraintType.PERMIT,
ContentEncryptionAlgorithmIdentifiers.AES_256_GCM));
jwe.setKey(key);
jwe.setCompactSerialization(jwtStringNew1);
System.out.println("JOSE4J ::: getHeaders :::: " + jwe.getHeaders());
System.out.println("JOSE4J ::: getContentEncryptionAlgorithm :::: " + jwe.getContentEncryptionAlgorithm());
System.out.println("JOSE4J ::: getEncryptedKey :::: " + jwe.getEncryptedKey());
System.out.println("JOSE4J ::: getIv :::: " + jwe.getIv());
System.out.println("JOSE4J ::: Payload :::: " + jwe.getPayload());
}

Jetty Java websocket client doesn't connect to server

I am using Java Jetty client written [websocket-client 9.3.8.RC0]. Websocket server is little wierd in our case.
It accepting request in format.
wss://192.168.122.1:8443/status?-xsrf-=tokenValue
Token Value is received in first Login POST request in which i get Token Value & Cookie header. Cookie is added as a header whereas token is given as a param.
Now question is : -
When i run below code it just call awaitclose() function in starting. But there is not other function called i.e. Onconnected or even Onclose.
Any help would be appreciated to debug it further, to see any logs or environment issue to see why Socket is not connected.
Trying to figure out following points to debug.
1. To check if client certificates are causing issue.
Tried with my python code wspy.py it work seemlessly fine.
Code is
public final class websocketxxx {
WebSocketClient client=null;
public websocketxxx (){
}
public void run(String host,String cookieVal, String xsrfVal, String resource) throws IOException {
SslContextFactory sslContextFactory = new SslContextFactory();
sslContextFactory.setTrustAll(true);
WebSocketClient client = new WebSocketClient(sslContextFactory);
MyWebSocket socket = new MyWebSocket();
try {
client.start();
ClientUpgradeRequest request = new ClientUpgradeRequest();
// Add the authentication and protocol to the request header
// Crate wss URI from host and resource
resource = resource + xsrfVal;
URI destinationUri = new URI("wss://" + host + resource); // set URI
request.setHeader("cookie",cookieVal);
request.setHeader("Sec-WebSocket-Protocol", "ao-json");
//System.out.println("Request Headers print : " request.getHeaders())
System.out.println("Connecting to : " + destinationUri);
client.connect(socket, destinationUri, request);
socket.awaitClose(5000, TimeUnit.SECONDS);
} catch (Throwable t) {
t.printStackTrace();
} finally {
try {
client.stop();
} catch (Exception e) {
e.printStackTrace();
}
}
}
#WebSocket
public class MyWebSocket {
private final CountDownLatch closeLatch = new CountDownLatch(1);
#OnWebSocketConnect
public void onConnect(Session session) {
System.out.println("WebSocket Opened in client side");
try {
System.out.println("Sending message: Hi server");
session.getRemote().sendString("Hi Server");
} catch (IOException e) {
e.printStackTrace();
}
}
#OnWebSocketMessage
public void onMessage(String message) {
System.out.println("Message from Server: " + message);
}
#OnWebSocketClose
public void onClose(int statusCode, String reason) {
System.out.println("WebSocket Closed. Code:" + statusCode);
}
public boolean awaitClose(int duration, TimeUnit unit) throws InterruptedException {
return this.closeLatch.await(duration, unit);
}
}
public Client getBypassCertVerificationClient() {
Client client1 = null;
try {
// Create a HostnameVerifier that overrides the verify method to accept all hosts
HostnameVerifier hostnameVerifier = new HostnameVerifier() {
public boolean verify(String host, SSLSession sslSession) {
return true;
}
};
// Create a TrustManager
TrustManager[] trust_mgr = new TrustManager[]{
new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(X509Certificate[] certs, String t) {
}
public void checkServerTrusted(X509Certificate[] certs, String t) {
}
}
};
// Create the SSL Context
SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, trust_mgr, new SecureRandom());
// Create the client with the new hostname verifier and SSL context
client1 = ClientBuilder.newBuilder()
.sslContext(sslContext)
.hostnameVerifier(hostnameVerifier)
.build();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyManagementException e) {
e.printStackTrace();
}
return client1;
}
public String[] simple_Login_POST_request(String host, String user, String password, String resource, String data) {
String resp = null;
String[] headers = new String[2];
try {
// Create a Client instance that supports self-signed SSL certificates
Client client = getBypassCertVerificationClient();
// Create a WebTarget instance with host and resource
WebTarget target = client.target("https://" + host).path(resource);
// Build HTTP request invocation
Invocation.Builder invocationBuilder = target.request();
// Encode the user/password and add it to the request header
invocationBuilder.header(HttpHeaders.CONTENT_TYPE, "application/x-www-form-urlencoded");
Form form = new Form();
form.param("userid", user);
form.param("password", password);
// Invoke POST request and get response as String
//post(Entity.entity(form,MediaType.APPLICATION_FORM_URLENCODED_TYPE));
Response response = invocationBuilder.method("POST", Entity.entity(form,MediaType.APPLICATION_FORM_URLENCODED_TYPE));
resp = (String) response.readEntity(String.class);
// Print input URL, input data, response code and response
System.out.println("URL: [POST] " + target.getUri().toString());
System.out.println("HTTP Status: " + response.getStatus());
System.out.println("HTTP Status: " + response.getHeaders());
headers[0] = response.getHeaderString("Set-Cookie");
//response.getStringHeaders()
headers[1] = response.getHeaderString("X-XSRF-TOKEN");
System.out.println("Response: \n" + resp);
response.close();
} catch (Exception e) {
e.printStackTrace();
}
return headers;
}
public static void main(String[] args) throws IOException {
String host = "";
String user = "";
String password = "";
String resource = "";
host ="192.168.122.1:8443";
user = "ADMIN";
password ="ADMIN";
websocketXXX wsNotification = new websocketxxx();
/////////////////////////////////////////////////////////////////
// Simple POST LOGIN Request
resource = "/api/login";
String headers[]= wsNotification.simple_Login_POST_request(host, user, password, resource, null);
////////////////////////////////////////////////////////////////
headers[0] = headers[0].substring(headers[0].lastIndexOf(",") + 1);
System.out.println("headers[0]: " + headers[0] + "\n");
String cookie = headers[0];
String XSRFToken = headers[1];
resource = "/status?-xsrf-=";
//wsNotification.simple_websocket_example(host, cookie, XSRFToken, resource);
wsNotification.run(host, cookie, XSRFToken, resource);
}
}
The implementation is mostly correct.
Setting raw Cookie and Sec-WebSocket-* headers is forbidden, you have to use the API.
Cookie handling from:
ClientUpgradeRequest request = new ClientUpgradeRequest();
request.setHeader("cookie",cookieVal);
To ClientUpgradeRequest.setCookies() :
ClientUpgradeRequest request = new ClientUpgradeRequest();
List<HttpCookie> cookies = new ArrayList<>();
cookies.add(new HttpCookie(...));
request.setCookies(cookies);
Note: if you are using the java CookieStore, then you can pass the CookieStore instance to the client as well, using the setCookiesFrom(CookieStore) method.
Sub Protocol Selection from:
ClientUpgradeRequest request = new ClientUpgradeRequest();
request.setHeader("Sec-WebSocket-Protocol", "ao-json");
To ClientUpgradeRequest.setSubProtocols():
ClientUpgradeRequest request = new ClientUpgradeRequest();
request.setSubProtocols("ao-json");

ASP.NET JSON Web Service Response format

I have written one simple web service which get product list in JSONText which is string object
Web Service code is below
using System;
using System.Collections.Generic;
using System.Web;
using System.Web.Services;
using System.Web.Script.Services;
using System.Runtime.Serialization.Json;
using System.IO;
using System.Text;
/// <summary>
/// Summary description for JsonWebService
/// </summary>
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.Web.Script.Services.ScriptService]
public class JsonWebService : System.Web.Services.WebService
{
public JsonWebService () {
//Uncomment the following line if using designed components
//InitializeComponent();
}
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public string GetProductsJson(string prefix)
{
List<Product> products = new List<Product>();
if (prefix.Trim().Equals(string.Empty, StringComparison.OrdinalIgnoreCase))
{
products = ProductFacade.GetAllProducts();
}
else
{
products = ProductFacade.GetProducts(prefix);
}
//yourobject is your actula object (may be collection) you want to serialize to json
DataContractJsonSerializer serializer = new DataContractJsonSerializer(products.GetType());
//create a memory stream
MemoryStream ms = new MemoryStream();
//serialize the object to memory stream
serializer.WriteObject(ms, products);
//convert the serizlized object to string
string jsonString = Encoding.Default.GetString(ms.ToArray());
//close the memory stream
ms.Close();
return jsonString;
}
}
now it give me resoponse like below :
{"d":"[{\"ProductID\":1,\"ProductName\":\"Product 1\"},{\"ProductID\":2,\"ProductName\":\"Product 2\"},{\"ProductID\":3,\"ProductName\":\"Product 3\"},{\"ProductID\":4,\"ProductName\":\"Product 4\"},{\"ProductID\":5,\"ProductName\":\"Product 5\"},{\"ProductID\":6,\"ProductName\":\"Product 6\"},{\"ProductID\":7,\"ProductName\":\"Product 7\"},{\"ProductID\":8,\"ProductName\":\"Product 8\"},{\"ProductID\":9,\"ProductName\":\"Product 9\"},{\"ProductID\":10,\"ProductName\":\"Product 10\"}]"}
But i am looking for below out put
[{"ProductID":1,"ProductName":"Product 1"},{"ProductID":2,"ProductName":"Product 2"},{"ProductID":3,"ProductName":"Product 3"},{"ProductID":4,"ProductName":"Product 4"},{"ProductID":5,"ProductName":"Product 5"},{"ProductID":6,"ProductName":"Product 6"},{"ProductID":7,"ProductName":"Product 7"},{"ProductID":8,"ProductName":"Product 8"},{"ProductID":9,"ProductName":"Product 9"},{"ProductID":10,"ProductName":"Product 10"}]
can any one tell me what is actual problem
Thanks
First there was a change with ASP.NET 3.5 for security reasons Microsoft added the "d" to the response. Below is a link from Dave Ward at the Encosia that talks about what your seeing:
A breaking change between versions of ASP.NET AJAX. He has several posts that talks about this that can help you further with processing JSON and ASP.NET
Actually, if you just remove the
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
from the method, and you return the jsonString that you serialized using the JavaScriptSerializer you will get exactelly the output that you were looking for.
Notice that u have double quotes beside ur array in your response.In this way u return json format not json object from ur web method.Json format is a string.Therefore u have to use json.parse() function in order to parse json string to json object.If u dont want to use parse fuction,u have to remove serialize in ur web method.Thus u get a json object.
in .net web service
[WebMethod]
public string Android_DDD(string KullaniciKey, string Durum, string PersonelKey)
{
return EU.EncodeToBase64("{\"Status\":\"OK\",\"R\":[{\"ImzaTipi\":\"Paraf\", \"Personel\":\"Ali Veli üğişçöıÜĞİŞÇÖI\", \"ImzaDurumTipi\":\"Tamam\", \"TamamTar\":\"1.1.2003 11:21\"},{\"ImzaTipi\":\"İmza\", \"Personel\":\"Ali Ak\", \"ImzaDurumTipi\":\"Tamam\", \"TamamTar\":\"2.2.2003 11:21\"}]}");
}
static public string EncodeToBase64(string toEncode)
{
UTF8Encoding encoding = new UTF8Encoding();
byte[] bytes = encoding.GetBytes(toEncode);
string returnValue = System.Convert.ToBase64String(bytes);
return returnValue;
}
in android
private static String convertStreamToString(InputStream is)
{
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line = null;
try
{
while ((line = reader.readLine()) != null)
{
sb.append(line + "\n");
}
}
catch (IOException e)
{
e.printStackTrace();
}
finally
{
try
{
is.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
return sb.toString();
}
private void LoadJsonDataFromASPNET()
{
try
{
DefaultHttpClient httpclient = new DefaultHttpClient();
HttpPost httpPostRequest = new HttpPost(this.WSURL + "/WS.asmx/Android_DDD");
JSONObject jsonObjSend = new JSONObject();
jsonObjSend.put("KullaniciKey", "value_1");
jsonObjSend.put("Durum", "value_2");
jsonObjSend.put("PersonelKey", "value_3");
StringEntity se = new StringEntity(jsonObjSend.toString());
httpPostRequest.setEntity(se);
httpPostRequest.setHeader("Accept", "application/json");
httpPostRequest.setHeader("Content-type", "application/json");
// httpPostRequest.setHeader("Accept-Encoding", "gzip"); // only set this parameter if you would like to use gzip compression
HttpResponse response = (HttpResponse) httpclient.execute(httpPostRequest);
HttpEntity entity = response.getEntity();
if (entity != null)
{
InputStream instream = entity.getContent();
String resultString = convertStreamToString(instream);
instream.close();
resultString = resultString.substring(6, resultString.length()-3);
resultString = new String(android.util.Base64.decode(resultString, 0), "UTF-8");
JSONObject object = new JSONObject(resultString);
String oDurum = object.getString("Status");
if (oDurum.equals("OK"))
{
JSONArray jsonArray = new JSONArray(object.getString("R"));
if (jsonArray.length() > 0)
{
for (int i = 0; i < jsonArray.length(); i++)
{
JSONObject jsonObject = jsonArray.getJSONObject(i);
String ImzaTipi = jsonObject.getString("ImzaTipi");
String Personel = jsonObject.getString("Personel");
String ImzaDurumTipi = jsonObject.getString("ImzaDurumTipi");
String TamamTar = jsonObject.getString("TamamTar");
Toast.makeText(getApplicationContext(), "ImzaTipi:" + ImzaTipi + " Personel:" + Personel + " ImzaDurumTipi:" + ImzaDurumTipi + " TamamTar:" + TamamTar, Toast.LENGTH_LONG).show();
}
}
}
}
}
catch (Exception e)
{
e.printStackTrace();
}
}