I've got Google's oauth2 working on my app, where id_token is a string delimited with periods. I read here that the id_token is delimited into three parts and the second part contains the actual payload. If I split the string apart and decode the second value I get what I expect using my account. What I don't understand though is when I try on my wife's account if I parse that second part to json an "unexpected character" error.
I've tried grabbing the string from the console and running it through an online base64 decoder and do see the json doesn't get evaluated correctly.
{"iss":"accounts.google.com","sub":"111475728886332985448","azp":"74770364428-621332j2r657ish4jh94n9n1k0mplpgd.apps.googleusercontent.com","email":"her.email#gmail.com","at_hash":"lSKFL86HsCeu7TU4tsYBTw","email_verified":true,"aud":"74300369428-621332j2r657ish4jh94n9n1k0mplpgd.apps.googleusercontent.com","iat":1414192526,"exp":191819642���
What could be different between the two accounts that would cause my email to return valid json and hers not to?
An id_token is a JSON Web Token (JWT), in this case using compact serialization. JWT elements are base64url encoded with no padding, which is slightly different from plain base64 encoding as can be seen from: https://datatracker.ietf.org/doc/html/draft-ietf-jose-json-web-signature-38#appendix-C
A nice id_token/JWT decoder can be found here: http://jwt.io/
You may have been lucky for your own id_token so that it did not need padding.
Related
I'm getting a body hash mismatch when the POST body of an XML web service request contains international characters.
From what I've read, it sounds like international characters in a POST body have to be encoded before calculating the OAuth body hash. UTF-8 for CAFÉ of "CAF%c3%89" doesn't seem to work with the MasterCard Match web service. I'm having trouble with the tool we're using (iWay Service Manager) re-interpreting "CAFÉ" back to "CAFÉ". Before I figure out how to squeeze an encoder in before the OAuth step, I was hoping to confirm with someone who had dealt with this issue. What is the proper encoding to use on a POST body with international characters (or is my problem likely to be something else)?
For calculating MasterCard OAuth body hash, the recommended encoding is UTF-8. Also the Core SDK made available by MasterCard uses UTF-8 encoder to encode oauth_body_hash.
I've been going around in circles from Apple's CCCrypto docs, frameworks and other SO answers and am not making any headway.
I think I need to figure out how to get a IV from an encrypted string that I receive.
I receive a JSON payload which contains a String. That string is encrypted in AES-256-CBC. (From a Laravel PHP instance that I think uses OpenSSL). The string itself, decrypted, is another JSON object.
I have a pre-defined key.
The string I receive looks something like:
eJahdkawWKajashwlkwAkajsne8ehAhdhsiwkdkdhwNIEhHEheLlwhwlLLLLhshnNWhwhabwiIWHWHwh=
(but is a lot longer).
I'm trying to use this answer here: Issue using CCCrypt (CommonCrypt) in Swift
But am a) unsure if I'm properly converting the string to data and b) how to get the IV (initialization vector) from the string I receive.
Using that answer I do get "success" however when I try to pass it to the NSJSONSerailizer I never got a good result (it always fails) but I do get data out - I think it's garbage.
Edit:
I really mis-understood my original problem - I was receiving a base64 encoded string that I needed to decode into JSON (which went fine). Then using the linked answer and importing CommonCrypto I thought I'd be able to get usable data but I am not. #Rob Napier 's answer is extremely helpful. I think my problem is that the instance of laravel in question is using OpenSSL.
There is no really commonly used standard format for AES encrypted data (there are several "standard formats" but they're not commonly used....) The only way to know how the data you have is encrypted is to look at the documentation for the data format, or failing that, the encrypting code itself.
In good encryption formats, the IV is sent along with the data. But in many common (insecure) formats, there is a hard-coded IV (sometimes 16 bytes of 0x00). If there's a password, you also need to find out how they've converted the password to a key (there are several ways to do this, some good, some horrible). In a good format, the key derivation may include some random "salt" that you need to extract from the data. You'll also need to know if there is an HMAC or similar authentication (which might be stored at the beginning or the end of the data, and may include its own salt).
There just isn't any good way to know without documentation from the sender. Any decently encrypted format is going to look like random noise, so figuring it out just by looking at the final message is pretty hard.
If this comes out of Laravel's encrypt function, then that seems to be ultimately this code:
public function encrypt($value)
{
$iv = mcrypt_create_iv($this->getIvSize(), $this->getRandomizer());
$value = base64_encode($this->padAndMcrypt($value, $iv));
// Once we have the encrypted value we will go ahead base64_encode the input
// vector and create the MAC for the encrypted value so we can verify its
// authenticity. Then, we'll JSON encode the data in a "payload" array.
$mac = $this->hash($iv = base64_encode($iv), $value);
return base64_encode(json_encode(compact('iv', 'value', 'mac')));
}
If this is correct, then you should have been passed base64-encoded JSON with three fields: the IV (iv), the ciphertext (value), and what looks like an HMAC encrypted using the same key as the plaintext (mac). The data you've given above doesn't look like JSON at all (even after base-64 decoding).
This assumes that the caller used this encrypt function, though. There are many, many ways to encrypt, though, so you need to know how the actual server you're talking to did it.
I am creating an email client with API functionalities. One of the functionalities is to provide an API call to download a given attachment.
To obtain an attachment, given the filename and unique email ID (using the GMail X-MSG-ID unique identifier), I'm downloading the whole email, using the FETCH command with the RFC822 command. This is naturally very heavy.
What I want to do is download only the BODY part that is that attachment, such as BODY[1], BODY[2], etc. I know that obtaining the BODYSTRUCTURE gives me a list of parts in the format ("PART","ETC")("PART","ETC"). What I want to know is how these parts map to the BODY[0], BODY[1], etc.
Is the order that parts appear in the BODYSTRUCTURE response a direct mapping to the BODY indices? So if calling BODYSTRUCTURE I obtain ("123","ETC")("456","ETC")("789","ETC"), can I assume that BODY[0] is the "123" and that BODY[1] is the "456"? Or is there another way to map the elements in parenthesis in a BODYSTRUCTURE response to the BODY[0], BODY[1], etc?
Thank you
I have solved this through trial and error.
It would appear the BODY indeces are as they come in the BODYSTRUCTURE response. So, using the above example, if in the BODYSTRUCTURE response you obtain ("123","ETC")("456","ETC"), then when you call BODY[1] you will obtain the "123" part, when you call BODY[2] you will obtain "456", and so on.
In Rails 3 (Ruby 1.9.2) I send an request
Started GET "/controller/action?path=/41_+"
But the parameter list looks like this:
{"path"=>"/41_ ",
"controller"=>"controller",
"action"=>"action"}
Whats going wrong here? The -, * or . sign works fine, its just the +which will be replaced by a space.
That's normal URL encoding, the plus sign is a shorthand for a space:
Within the query string, the plus sign is reserved as shorthand notation for a space. Therefore, real plus signs must be encoded. This method was used to make query URIs easier to pass in systems which did not allow spaces.
And from the HTML5 standard:
The character is a U+0020 SPACE character
Replace the character with a single U+002B PLUS SIGN character (+).
For POST-requests, (in case that's how some of you stumbled upon this question, like me) one might encounter this problem because one has encoded the data in the wrong way on the client side. Encoding the data as application/x-www-form-urlencoded will tell rails to decode the data as it decodes a URL, and hence replace + signs with whitespace, according to the standard RFC1738 as explained by #mu is too short
The solution is to encode the data on the client side as multipart/form-data.
In PHP, using cURL, this is done by taking into consideration the following gotcha:
Passing an array to CURLOPT_POSTFIELDS will encode the data as
multipart/form-data, while passing a URL-encoded string will encode
the data as application/x-www-form-urlencoded. http://php.net/manual/en/function.curl-setopt.php
You might wonder why I was using PHP on the client side (that's because the client in my example was another webserver, since I'm working on an API connection.)
How many characters long can an oauth access token and oauth access secret be and what are the allowed characters? I need to store them in a database.
I am not sure there are any explicit limits. The spec doesn't have any.
That said, OAuth tokens are often passed as url parameters and so have some of the same limitations. ie need to be properly encoded, etc.
OAuth doesn't specify the format or content of a token. We simply use encrypted name-value pairs as token. You can use any characters in token but it's much easier to handle if the token is URL-safe. We achieve this by encoding the ciphertext with an URL-safe Base64.
As most people already pointed out. The OAuth specification doesn't give you exact directions but they do say...
cited from: https://datatracker.ietf.org/doc/html/draft-hammer-oauth-10#section-4.9
"Servers should be careful to assign
shared-secrets which are long enough,
and random enough, to resist such
attacks for at least the length of
time that the shared-secrets are
valid."
"Of course, servers are urged to err
on the side of caution, and use the
longest secrets reasonable."
on the other hand, you should consider the maximum URL length of browsers:
see: http://www.boutell.com/newfaq/misc/urllength.html
If you read the spec, it says,
The authorization server issues the registered client a client
identifier - a unique string representing the registration
information provided by the client. The client identifier is not a
secret; it is exposed to the resource owner, and MUST NOT be used
alone for client authentication. The client identifier is unique to
the authorization server.
The client identifier string size is left undefined by this
specification. The client should avoid making assumptions about the
identifier size. The authorization server SHOULD document the size
of any identifier it issues.
Second, Access Token should be sent as header, not as a URL param.
Authorization: Bearer < token>.
An OAuth token is conceptually an arbitrary-sized sequence of bytes, not characters. In URLs, it gets encoded using standard URL escaping mechanisms:
unreserved = ALPHA, DIGIT, '-', '.', '_', '~'
Everything not unreserved gets %-encoded.
I'm not sure whether you just talk about the oauth_token parameter that gets passed around. Usually, additional parameters need to be stored and transmitted as well, such as oauth_token_secret, oauth_signature, etc. Some of them have different data types, for example, oauth_timestamp is an integer representing seconds since 1970 (encoded in decimal ASCII digits).
Valid chars for OAuth token are limited by HTTP header value restrictions as OAuth token is frequently sent in HTTP header "Authorization".
Valid chars for HTTP headers are specified by https://www.rfc-editor.org/rfc/rfc7230#section-3.2.6. Alternatively you may check HTTP header validating code of some popular HTTP client libs, for example see Headers.checkNameAndValue() util of OkHttp framework: https://github.com/square/okhttp/blob/master/okhttp/src/main/java/okhttp3/Headers.java
And this is not all. I wouldn't include HTTP header separator (; and many others) and whitespace symbols (' ' and '\t') and double quote (") (see https://www.rfc-editor.org/rfc/rfc7230#section-3.2.6) as it would require to escape OAuth token before using in HTTP header. Frequently tokens are used by humans in curl test requests, and so good token generators don't add such characters. But you should check what characters may produce Oauth token generator with which your service is working before making any assumptions.
To be specific, even if Oauth spec doesn't say anything, if you are using java and mysql then it will be 16 characters as we generally generate the tokens using UUID and store it as BINARY(16) in the database. I know these details as I have recently done the development using OAuth.