I have developed a restful service using C# .net,by using this service i have to validate the user login and password through android app developed in android studio.Now the password can contain special characters and in my case password is abc123* and URL become like this
http://srvcallnimbus.azurewebsites.net/srvcallnimbus.svc/validateuserByCompanyName/testPhone/test#test.biz/abc123
But this does not pass to the service correctly and my android app return error.I have tried all answers at stockoverflow.But abc123 dows not get into encoded form.URLEncoder.Encode(password) does not encode the * character.
I found a solution as follow
Following steps involve to solve above mentioned problem
Encode Your password in android app.
Decode your password in WCF restful service.
Encode Password in Android App.
Use the following method to encode your password in android app(encoding in base 64)
String base64Pass=""
string password="abc123*"
byte byteData[] =password.getBytes();
base64Pass= Base64.encodeToString(byteData, Base64.NO_WRAP);
Decode password in WCF restful service
Use the following way to decode your password in WCF Restful service.
String data = password; //passed as parameter
System.Text.UTF8Encoding encoder = new System.Text.UTF8Encoding();
System.Text.Decoder utf8Decode = encoder.GetDecoder();
byte[] todecode_byte = Convert.FromBase64String(data);
int charCount = utf8Decode.GetCharCount(todecode_byte, 0, todecode_byte.Length);
char[] decoded_char = new char[charCount];
utf8Decode.GetChars(todecode_byte, 0, todecode_byte.Length, decoded_char, 0);
string result = new String(decoded_char); //Decoded String
Related
This question can be a possible duplicate of the question here, but I need a little bit more info on the subject. My partner(android) and me(ios) are trying to exchange some data, which is an identity key. This key is generated through the curve25519 wrapper of the Signal Protocol. The key consists of a public as well as a private key. The key is of the type defined here as ECKeyPair. Now I want to transfer the publicKey as NSData with each other, read iOS to Android and vice versa. The approaches taken and resulting issues are listed below.
From iOS, tried to make the data(publicKey) as a base64 encoded string and used json serialisation to transfer to Android, But android is not able to decode the base64 string correctly. I feel its because while converting the key to base64 the data size is changed somehow, for eg when I print the data the size is always more than the 32 bytes its supposed to be. The algorithm which check for the data validation rejects the public key from within the Android implementation saying not a valid data for the key.
Tried to transfer the public key from Android to iOS by casting as a ByteArray. The byte array created from the Android consists of Signed Integers and I am not able to invoke Data(bytes: <Array<UInt8>>) because its applicable to Unsigned Integers. When I try to convert this to signed Integers then it results in a similar validity check failure like in point one mentioned above.
An almost similar scenario is described in this issue here. So I would like to know the following.
Why is it that some data, which is base64 encoded in a particular plateform, like iOS, differes when decoded in another platform, say Android.
Why cant iOS succesfully read in a ByteArray created by an Android OS. Or am I mistaken? If so please guide me.
How can I transfer data between iOS and Android successfully like in this particular case? I am familiar with normal data transfers like images or files, but its just not working in my case of cryptographic data. I know about ProtoBuff and for the sake of feasibility I would prefer json or likewise.
Adding some details that might be helpfull.
The publickey generated at iOS
The public key generated at Android.
[12,-55,99,72,15,-101,99,-13,99,-56,-47,19,-21,90,-17,-39,-119,-33,44,-87,-18,-24,-53,-29,-100,34,-60,69,-61,24,8,92].
Do note the difference in signs between iOS and Android.
Any help is appreciated.
Thank You
EDIT: Adding the exception screen shot at android.
As you can see the data is discarded as BadKey Type. I transferred the data from iOS to Android by Base64Encoding to string.
Its long time but for that particular scenario I used Hex String. Please be known hex string conversion for large data like videos is impractical as it freezes the device.
Also, sometime later for another project, I have implemented a simple encryption between Android and iOS. And these are what I used. Maybe this will help. These use base64 encoding.
Android Encryption and Decryption
val cryptor = AES256JNCryptor();
val password = "6dpC295ei9"
val text = yourString.toByteArray(charset("UTF-8"))
val encrypt = cryptor.encryptData(text, password.toCharArray()) // your encryption
val encode = Base64.encodeToString(encrypt, Base64.NO_WRAP) // encryptedtext
val decode = Base64.decode(encode, Base64.NO_WRAP)
val text = String(cryptor.decryptData(decode, password.toCharArray())) // your decryption
iOS Encryption and Decryption
let password = "6dpC295ei9"
extension String {
var encrypted : String? {
guard let plainData = data(using: .utf8) else {
return nil
}
return RNCryptor.encrypt(data: plainData, withPassword: password).base64EncodedString(options: .init(rawValue: 0))
}
var decrypted : String? {
guard let cipherData = Data.init(base64Encoded: self, options: .init(rawValue: 0)), let plainData = try? RNCryptor.decrypt(data: cipherData, withPassword: password), let plainText = String(bytes: plainData, encoding: .utf8) else {
return "~ DECRYPTION FAILED ~"
}
return plainText
}
}
I try to send the user key in String to onine server and make request, but it just send the string before the symbols. Any idea how to make Android read through but not remove the symbols? I mean all the symbols.
The following method is replace the [space] so the PHP can read my link
String sText = ""+autoTv.getText().toString().replace(" ","%20")+"";
SearchRequest t = new SearchRequest();
t.execute(sText);
I am calling a web service through async task which is returning text in strange format. here is sample string
dhmot_enot = Ï. ÎÎ®Î¼Î¿Ï ÎοÏλαÏ
zoe_name = Î.Î.Î: ÎÏÎ½ÎµÏ Î ÏοÏÏαÏÎ¯Î±Ï ÎÏοÏÏ Î¥Î¼Î·ÏÏοÏ
zones_zoe = ÎΩÎÎ Î: ÎÎ ÎÎΥΤΠΠΡÎΣΤÎΣÎΠΤÎΣ ΦΥΣÎΣ
zoe_fek = 187/Î/2011
fek_rel = 544/Î/1978
yphresia = Î¥.ÎÎÎ Î. ÎάÏηÏ-ÎοÏλαÏ-ÎοÏλιαγμÎνηÏ
How to find and resolve this ?
Update 1
Here is the actual service link that i am calling from server (works well in web browser ) but when i call from android it looks like above
http://geo-polis.gistemp.com/geoserver/wms?service=WMS&version=1.1.1&srs=EPSG:4326&bbox=23.733829893171787,37.75098946973509,23.839769437909126,37.89294194933182&styles=&&buffer=20&OUTPUTFORMAT=json&request=GetFeatureInfo&layers=geopolis:oria_eniaiou_dhmou&query_layers=geopolis:oria_eniaiou_dhmou&width=1080&height=1832&x=690&y=821
The response is a normal UTF-8 encoded stream of data. To see this, go to the URL you show in your post in the browser, and look at the encoding it picked automatically: it'll show unicode/utf-8 as character encoding for the response. If you change that, forcing the browser to decode it as if it's ANSI encoded (windows codepage 1252/ISO-8859-15) then the text turns into the gibberish you were showing in your question, so: you're not decoding the data correctly, and need to make sure to decode as utf8.
I am having a curious problem that perhaps someone has insight into. I encode a query string into a URL on Android using the following code:
request = REQUEST_BASE + "?action=loadauthor&author=" + URLEncoder.encode(author, "UTF-8");
I then add a few other parameters to the string and create a URI like this:
uri = new URI(request);
At a certain point, I pull out the query string to make a checksum:
uri.getRawQuery().getBytes();
Then I send it on its way with:
HttpGet get = new HttpGet(uri);
On the Appengine server, I then retrieve the string and try to match the checksum:
String query = req.getQueryString();
Normally, this works fine. However, there are a few characters that seem to get unencoded on the way to the server. For example,
action=loadauthor&author=Charles+Alexander+%28Ohiyesa%29+Eastman×tamp=1343261225838&user=1479845600
shows up in the server logs (and in the GAE app) as:
action=loadauthor&author=Charles+Alexander+(Ohiyesa)+Eastman×tamp=1343261226837&user=1479845600
This only happens to a few characters (like parentheses). Other characters remain encoded all the way through. Does anyone have a thought about what I might be doing wrong? Any feedback is appreciated.
I never did find a solution for this problem. I worked around it by unencoding certain characters on the client before sending things to the server:
request = request.replace("%28", "(");
request = request.replace("%29", ")");
request = request.replace("%27", "'");
If anyone has a better solution, I am sure that I (and others) would be interested!
URLEncoder does not encode parentheses and certain other characters, as they are supposed to be "safe" for most servers. See URLEncoder. You will have to replace these yourself if necessary.
Example:
URI uri = new URI(request.replace("(","%28"));
If a lot of replacements are needed, you can try request.replaceAll(String regularExpression, String replacement). This, of course, requires knowledge of regular expressions.
In my browser, or in iOS, when I try to get the contents of a URL with encoded http authentication information in the form
http://myUser:myPassword#www.example.com/secure/area/index.html
It just works. I'm getting URLs from a web service, and I'd like to avoid trying to parse them up for their HTTP auth info if I can help it. Is there a way to do something similar in Android without actually parsing the URLs? Alternatively, what is the best way to go about that?
UPDATE:
I find that when I try to set the authentication information in an Authorization header, I get a very strange FileNotFoundException.
Here's the code I'm using:
URL url = new URL(urlString);
URLConnection connection;
String authority = url.getAuthority();
if (authority.contains("#")) {
String userPasswordString = authority.split("#")[0];
url = new URL(urlString.replace(userPasswordString + "#", ""));
connection = url.openConnection();
String encoded = new String(Base64.encode(userPasswordString.getBytes(), Base64.DEFAULT), "UTF-8");
connection.setRequestProperty("Authorization", "Basic " + encoded);
} else {
connection = url.openConnection();
}
InputStream responseStream = connection.getInputStream();
All the info seems to check out, I've verified the url is correct, the base64 string is correct, and the file is certainly on the server--I have no trouble at all opening it with Firefox, and Firebug shows all the right headers, matching what I've sent as far as I can tell. What I get though is the following error (url host changed to protect the innocent):
java.io.FileNotFoundException: http://a1b.example.com/grid/uploads/profile/avatar/user1/custom-avatar.jpg
at org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1061)
Any idea what this is all about?
I looked into using HttpClient, but saw that in Issue 16041 it is recommended that we prefer URLConnection.
That looks like your browser is applying some extra rules to parsing the URL. In Android you can use HTTP Client's authentication mechanism such as BASIC and DIGEST to do the same things. Which one you choose is dependent on the server you are trying to authenticate against.
Here is a good page to get you started.
Unfortunately, on Android you can't pass the user info (username/password) in that format to either java.net.URL or HttpClient and have it work like in a browser.
I'd recommend using URI (see http://download.oracle.com/javase/1.5.0/docs/api/index.html?java/net/URI.html) to do this: pass your URL to the URI constructor that takes a String and then you can extract the user info (using getUserInfo()). You can then either use HttpClient's authorization classes (see http://developer.android.com/reference/org/apache/http/auth/package-summary.html) or build the basic auth header yourself (an example is given at http://www.avajava.com/tutorials/lessons/how-do-i-connect-to-a-url-using-basic-authentication.html).