I am currently using the following code to encrypt password but it is without using key.
package com.MD5Check;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import android.app.Activity;
import android.os.Bundle;
public class MD5Check extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
getSignature();
}
public void getSignature()
{
try {
String s = "aditi9970";
MessageDigest md5 = MessageDigest.getInstance("MD5");
md5.update(s.getBytes(),0,s.length());
String signature = new BigInteger(1,md5.digest()).toString(16);
System.out.println("Signature: "+signature);
} catch (final NoSuchAlgorithmException e) {
e.printStackTrace();
}
}
}
I would like to hash the password using md5 with key in android.
Can anybody suggest the right way to do this?
MD5 is a hashing algorithm - meaning that the function will only transform data one way (from the original into an md5 hash). I am a little unclear what you mean by 'key' in these circumstances. If you are looking to salt the string before hashing it then you can simply concatenate your original string and your salt.
Alternatively you may wish to look at alternative android encryption techniques. I would start here http://developer.android.com/reference/javax/crypto/package-summary.html
Related
Flutter app receives public key in the form of contents of public.pem file which would be a string like "-----BEGIN PUBLIC KEY-----
MIICqq7DBi9sBXZfDYJC+G57JYUCAwEAAQ==
....
-----END PUBLIC KEY-----".
We also have a hashed string like "yBuHq6gZ...dgWs=".
Algorithm used to hash was RSA and following nodejs code was executed to generate the keys:
crypto.generateKeyPairSync('rsa',
{
modulusLength: modulusLength,
namedCurve: 'secp256k1',
publicKeyEncoding: {
type: 'spki',
format: 'pem'
},
privateKeyEncoding: {
type: 'pkcs8',
format: 'pem',
cipher: 'aes-256-cbc',
passphrase: passphrase
}
});
I wish to decrypt the hashed value. It was easy in nodejs by using the crypto library but I can't find how to do it in dart (Flutter).
Yeah, it was a misconception only. I needed both the key, original text and signature to verify the signature. I thought that with only key and signature I can get original text which is not possible.
This is my example. I hope that will be helpful.
dependencies:
encrypt: ^5.0.1
import 'package:encrypt/encrypt.dart';
import 'package:pointycastle/export.dart';
import 'dart:convert';
/// RSA decrypt by public key
/// PKCS1
String decryptByPublicKey(String public, String content) {
RSAKeyParser parser = RSAKeyParser();
RSAPublicKey publicKey = parser.parse(public) as RSAPublicKey;
AsymmetricBlockCipher cipher = PKCS1Encoding(RSAEngine());
cipher
..init(false, PublicKeyParameter<RSAPublicKey>(publicKey));
return utf8.decode(cipher.process(Encrypted.fromBase64(content).bytes));
}
I am baffled by what's happening.
I put the file name "Help" into the Extras of the Intent that I then immediately start. (There can't be any problems with this first code block. With breakpoint after putExtra, Watch expression helpIntent.getStringExtra(PACKAGE_NAME + ".filename") returned "Help".)
import static com.dslomer64.sqhell.BuildConfig.APPLICATION_ID;
...
public class MainActivity extends Activity
{
public final static String PACKAGE_NAME = APPLICATION_ID;
...
#Override public boolean onOptionsItemSelected(MenuItem item)
{
if(item.toString().equals("Help") || item.toString().equals("Acknowledgements"))
{
Intent
helpIntent;
helpIntent = new Intent(this, HelpActivity.class);
helpIntent.putExtra(PACKAGE_NAME + ".filename", item.getTitle().toString());
startActivity(helpIntent);
return true;
}
...
}
The fun begins in the spawned Intent:
public class HelpActivity extends Activity
{
...
public void showHelp(AssetManager assets, String filename)
{
try
{
////////////////////////////////////////////
// filename = null ********* #1
stream = assets.open(filename);
//////////////////////////////////////////// }
catch (IOException e) { e.printStackTrace(); }
...
}
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
Log.w("`````Help", "onCreate--bundle info: " + bundle.toString()) ;
Log.w("`````Help","onCreate--bundle key: " + bundle.getString("filename") );
Bundle bundle = getIntent().getExtras();
setContentView(R.layout.activity_help);
////////////////////////////////////////////
String fn = bundle.getString((PACKAGE_NAME + ".filename"));
// fn = null ***************************** #2
////////////////////////////////////////////
showHelp(getAssets(), fn );
}
The first sign of trouble (#1) was "filename is empty". Tracing back was easy. Now we're at #2, where--just compare--I use the same basic syntax to try to get the filename "Help" out of the Extras of the Intent. But it's null.
I'm not an expert with Intent but I've successfully used one a few times in the past.
I guess if I supplied a compilable program that shows the error it would be easier. But ...
If nobody spots anything right off, I'll get on that.
But it's straightforward!
But not.
================
EDIT
I added 2 Log statements (see above) and got this output:
W/`````Help: onCreate--bundle info:
Bundle[{com.dslomer64.sqhell.filename=Help}]
//////////////////////////////////////^^^^
W/`````Help: onCreate--bundle key: null
Not sure how this helps since it looks like "Help" is where it should be. And I assume key is null is equivalent to the original problem about filename being null.
============================
EDIT #2: Here's the WHOLE HelpActivity class. If this doesn't help, I'll get on the compilable thing:
package com.dslomer64.sqhell;
import android.app.Activity;
import android.content.res.AssetManager;
import android.os.Bundle;
import android.util.Log;
import android.view.WindowManager;
import android.widget.EditText;
import java.io.IOException;
import java.io.InputStream;
import java.util.Scanner;
import static android.provider.ContactsContract.Directory.PACKAGE_NAME;
public class HelpActivity extends Activity
{
Scanner scDict;
InputStream stream;
EditText help;
public void showHelp(AssetManager assets, String filename)
{
help = /*(EditText)*/ findViewById(R.id.txaHelp);
try
{
stream = assets.open(filename);
}
catch (IOException e) { e.printStackTrace(); }
scDict = new Scanner(stream).useDelimiter("\n\r\t ,.:;-( )"); // added (SPACE) recently
help.getText().clear();
while(scDict.hasNext())
help.append(scDict.next());
hideKeyboard();
help.setSelection(0);
}
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
Bundle bundle = getIntent().getExtras();
setContentView(R.layout.activity_help);
Log.w("`````Help", "onCreate--bundle info: " + bundle.toString()) ;
Log.w("`````Help", "onCreate--bundle key: " + bundle.getString(PACKAGE_NAME + ".filename"));
String fn = bundle.getString(PACKAGE_NAME + ".filename");
showHelp(getAssets(), fn );
}
}
=========================
In following cricket's advice, I noticed a long line in the importarea:
import static android.provider.ContactsContract.Directory.PACKAGE_NAME;
I don't remember ever seeing such before. So I took it out and got a few errors, wherever PACKAGE_NAME was used. Since each line had the "red underline" indicating use keypress 'Alt-Enter' for an easy import construction, I found that I HAD TWO CHOICES: the one above and MainActivity.PACKAGE_NAME.
I assume the previous time I did this, I chose the wrong item to import.
All is well.
Spent... too long on this.
Thanks to all who helped and Cricket for steering me in the right direction.
=====================
FINAL EDIT:
All I needed to do all along was delete the long import statement. And also pay attention to what I selected after doing it.
Criminey.
I thought I was doing what Cricket suggested all along. Didn't get the funny import in other classes. Why here????
it looks like "Help" is where it should be.
It does
... key is null
Its actually the value, but you're getting the value of the key "filename", not PACKAGE_NAME + ".filename", which is what you used in the putExtra.
The keys don't match, so the value is null
Suggestion: define your own constant like
public static final String FILENAME_EXTRA = APPLICATION_ID + ".filename";
and use that in all classes
Additionally your Scanner and everything requiring the file to be opened should be inside the try block.
you put data in the Intent, not the Bundle.
So, try String fn = getIntent().getStringExtra(PACKAGE_NAME + ".filename").Then you will find what you want.
you are using a wrong key when retrieving the value.
Log.w("`````Help","onCreate--bundle key: " + bundle.getString(PACKAGE_NAME + ".filename") );
I am trying to run an HTTPS Server on an Android device using NanoHttpd (my final goal is to run WSS server on Android). I successfully ran HTTP Server and Websocket using NanoHttpd on Android. I generated the key on MAC using this command and copied it onto my device:
keytool -genkey -keystore key.keystore -storepass keypass -storetype BKS -provider org.bouncycastle.jce.provider.BouncyCastleProvider
I wrote the following code:
keyStore = KeyStore.getInstance("BKS");
keyStore.load(stream, keyStorePwd.toCharArray());
keyManagerFactory = KeyManagerFactory
.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(keyStore, keyStorePwd.toCharArray());
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(keyManagerFactory.getKeyManagers(), null, null);
server.makeSecure(sc.getServerSocketFactory());
server.start();
I tested this on Chrome 38 and 42 with "Minimum SSL/TLS" flag set to "SSLv3". But when I want to connect to the server I keep receiving "ERR_SSL_VERSION_OR_CIPHER_MISMATCH" error.
I tried different instances of protocol (SSL/TLS), on multiple machines, and browsers. I tried NanoHttpd SSLServerSocketFactory method. But the error is the same.
I already looked at some samples including:
https://github.com/NanoHttpd/nanohttpd/issues/139
Does anyone have any comment on this?
After Hours of toil, I've got it!
Here is MY (working) code:
// I placed this block right below my class declaration so it runs
// as soon as the class is defined. (this is for localhost testing ONLY!!!!)
static {
//for localhost testing only
javax.net.ssl.HttpsURLConnection.setDefaultHostnameVerifier(
new javax.net.ssl.HostnameVerifier(){
public boolean verify(String hostname,
javax.net.ssl.SSLSession sslSession) {
if (hostname.equals("localhost")) {
return true;
}
return false;
}
});
}
// then in an init function, I set it all up here
this.secureAppServer = new NanoHTTPD(9043);
File f =new File("src/main/resources/key001.jks");
System.setProperty("javax.net.ssl.trustStore", f.getAbsolutePath());
this.secureAppServer.setServerSocketFactory(new SecureServerSocketFactory(NanoHTTPD.makeSSLSocketFactory("/" +f.getName(), "myawesomepassword".toCharArray()), null));
this.secureAppServer.start();
Here is the actual NanoHttpd Test case which illustrates exactly how its done Nano style.
package fi.iki.elonen;
import java.io.File;
/*
* #%L
* NanoHttpd-Core
* %%
* Copyright (C) 2012 - 2015 nanohttpd
* %%
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the nanohttpd nor the names of its contributors
* may be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* #L%
*/
import java.io.IOException;
import java.util.Arrays;
import javax.net.ssl.SSLServerSocket;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpTrace;
import org.apache.http.impl.client.DefaultHttpClient;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import fi.iki.elonen.NanoHTTPD.SecureServerSocketFactory;
public class SSLServerSocketFactoryTest extends HttpServerTest {
#Test
public void testSSLConnection() throws ClientProtocolException, IOException {
DefaultHttpClient httpclient = new DefaultHttpClient();
HttpTrace httphead = new HttpTrace("https://localhost:9043/index.html");
HttpResponse response = httpclient.execute(httphead);
HttpEntity entity = response.getEntity();
Assert.assertEquals(200, response.getStatusLine().getStatusCode());
Assert.assertEquals(9043, this.testServer.getListeningPort());
Assert.assertTrue(this.testServer.isAlive());
}
#Test
public void testCreatePassesTheProtocolsToServerSocket() throws IOException {
// first find the supported protocols
SecureServerSocketFactory secureServerSocketFactory = new SecureServerSocketFactory(NanoHTTPD.makeSSLSocketFactory("/keystore.jks", "password".toCharArray()), null);
SSLServerSocket socket = (SSLServerSocket) secureServerSocketFactory.create();
String[] protocols = socket.getSupportedProtocols();
// remove one element from supported protocols
if (protocols.length > 0) {
protocols = Arrays.copyOfRange(protocols, 0, protocols.length - 1);
}
// test
secureServerSocketFactory = new SecureServerSocketFactory(NanoHTTPD.makeSSLSocketFactory("/keystore.jks", "password".toCharArray()), protocols);
socket = (SSLServerSocket) secureServerSocketFactory.create();
Assert.assertArrayEquals("Enabled protocols specified in the factory were not set to the socket.", protocols, socket.getEnabledProtocols());
}
#Before
public void setUp() throws Exception {
System.setProperty("javax.net.ssl.trustStore", new File("src/test/resources/keystore.jks").getAbsolutePath());
this.testServer = new TestServer(9043);
this.testServer.setServerSocketFactory(new SecureServerSocketFactory(NanoHTTPD.makeSSLSocketFactory("/keystore.jks", "password".toCharArray()), null));
this.tempFileManager = new TestTempFileManager();
this.testServer.start();
try {
long start = System.currentTimeMillis();
Thread.sleep(100L);
while (!this.testServer.wasStarted()) {
Thread.sleep(100L);
if (System.currentTimeMillis() - start > 2000) {
Assert.fail("could not start server");
}
}
} catch (InterruptedException e) {
}
}
#After
public void tearDown() {
this.testServer.stop();
}
}
The other answers didn't work for me. I had to create a BKS-V1 Keystore using a KeyStore Explorer and save it to android assets folder as "keystore.bks". Alternatively, You can also use the following code to make the KeyStore file then just open it using KeyStore Explorer and change its type to BKS-V1.
keytool -genkey -keyalg RSA -alias selfsigned -keystore keystore.bks -storepass myKeyStorePass -validity 360 -keysize 2048 -ext SAN=DNS:localhost,IP:127.0.0.1 -validity 9999
I used the following code to make it work.
package com.example.myappname
import java.io.IOException;
import java.io.InputStream;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import javax.net.ssl.KeyManagerFactory;
import fi.iki.elonen.NanoHTTPD;
public class Server extends NanoHTTPD {
public Server(int port) throws IOException, KeyStoreException, CertificateException, NoSuchAlgorithmException, UnrecoverableKeyException {
super(port);
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
InputStream keyStoreStream = context.get().getAssets().open("keystore.bks");
keyStore.load(keyStoreStream, "myKeyStorePass".toCharArray());
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(keyStore, "myCertificatePass".toCharArray());
makeSecure(NanoHTTPD.makeSSLSocketFactory(keyStore, keyManagerFactory), null);
}
#Override
public Response serve(IHTTPSession session) {
}
}
To use it just write the following code and you will have an HTTPS server running on your Android device.
Server server = new Server(8080);
server.start(NanoHTTPD.SOCKET_READ_TIMEOUT, false);
This code is made possible thanks to the example provided in the following Github issue comment.
https://github.com/NanoHttpd/nanohttpd/issues/535#issuecomment-479269044
Modified from Decoded's solution since I was not able to use JKS type of keystore.
Instead I use Keystore Explorer to generate a BKS key.
Select BKS-V1 as type of the new KeyStore, then setup the NanoHTTPD server before start:
androidWebServer = new AndroidWebServer(port);
File f = new File("src/main/resources/localkey.bks");
System.setProperty("javax.net.ssl.trustStore", f.getAbsolutePath());
androidWebServer.setServerSocketFactory(new AndroidWebServer.SecureServerSocketFactory(AndroidWebServer.makeSSLSocketFactory("/" + f.getName(), "yourKeyStorePass".toCharArray()), null));
androidWebServer.start();
This link has solution: https://www.baeldung.com/nanohttpd#https
use keytool generate jks
keytool -genkey -keyalg RSA -alias selfsigned
-keystore keystore.jks -storepass your_password -validity 360
-keysize 2048 -ext SAN=DNS:localhost,IP:127.0.0.1 -validity 9999
move keystore.jks to project src/main/resources
and use following code:
public class HttpsExample extends NanoHTTPD {
public HttpsExample() throws IOException {
super(8080);
makeSecure(NanoHTTPD.makeSSLSocketFactory(
"/keystore.jks", "password".toCharArray()), null);
start(NanoHTTPD.SOCKET_READ_TIMEOUT, false);
}
// main and serve methods
}
I've got an app where I'm seeing the following stack trace in the play developer console:
java.lang.NoClassDefFoundError: android.security.MessageDigest
at com.google.android.maps.KeyHelper.getSignatureFingerprint(KeyHelper.java:60)
at com.google.android.maps.MapActivity.createMap(MapActivity.java:513)
at com.google.android.maps.MapActivity.onCreate(MapActivity.java:409)
...
the play console lists all these devices as type "OTHER". This is only happening to something like 1% of my users. What could be causing this? What could I do to fix it?
Thanks
android.security.MessageDigest was removed in Honeycomb, though there's no official record of this on android.com AFAIK
Try using java.security.MessageDigest in your import instead. Its been around since API 1 as well, so it will work on older devices, as well as Honeycomb and above. Just change the line:
import android.security.MessageDigest;
To
import java.security.MessageDigest;
The MessageDigest class is a helper class used to encode/decode keys, using common methods such as MD5 or SHA-1.
It seems that the class android.security.MessageDigest was removed from Honeycomb and later releases of Android, and must be replaced by java.security.MessageDigest (see this page)
Try downloading the latest version of the Google Maps API and rebuild your application with targetSDK set to the highest available (it should be 16 / Jelly Bean).
or
I have found simple work around! Just create in src directory package android\security and place MessageDigest.java inside.
package android.security;
import java.security.NoSuchAlgorithmException;
public class MessageDigest
{
private java.security.MessageDigest instance;
public MessageDigest() {}
private MessageDigest(java.security.MessageDigest instance)
{
this.instance = instance;
}
public static MessageDigest getInstance(String algorithm) throws NoSuchAlgorithmException
{
if (algorithm == null) return null;
try
{
if (algorithm.equals("SHA-1"))
return (MessageDigest) Class.forName("android.security.Sha1MessageDigest").newInstance();
else if (algorithm.equals("MD5"))
return (MessageDigest) Class.forName("android.security.Md5MessageDigest").newInstance();
}
catch (Exception e) {}
return new MessageDigest(java.security.MessageDigest.getInstance(algorithm));
}
public void update(byte[] input)
{
instance.update(input);
}
public byte[] digest()
{
return instance.digest();
}
public byte[] digest(byte[] input)
{
return instance.digest(input);
}
}
Hi i am using the following code to parse a certificate details.Everything is fine except a bit problem mentioned below.
package android.net.http;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileReader;
import java.io.InputStream;
import java.security.cert.Certif`enter code here`icate;
import java.security.cert.CertificateFactory;
import java.security.cert.CertificateParsingException;
import java.security.cert.X509Certificate;
import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;
import android.util.Base64;
import android.util.Base64InputStream;
import android.util.Log;
public class SslCertificate1Activity extends Activity
{
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
try {
String text = "-----BEGIN CERTIFICATE-----\n"+
"MIIC/TCCAmagAwIBAgIBKjANBgkqhkiG9w0BAQQFADCBqDEiMCAGA1UEAxMZeG1sZ2F0ZXdheS5p\n"+
"dHMudXRleGFzLmVkdTEoMCYGA1UECxMfSW5mb3JtYXRpb24gVGVjaG5vbG9neSBTZXJ2aWNlczEq\n"+
"MCgGA1UEChMhVGhlIFVuaXZlcnNpdHkgb2YgVGV4YXMgYXQgQXVzdGluMQ8wDQYDVQQHEwZBdXN0\n"+
"aW4xDjAMBgNVBAgTBVRleGFzMQswCQYDVQQGEwJVUzAeFw0wNDA1MDkwNTMwMTBaFw0wNTA1MDQw\n"+
"NTMwMTBaMIGAMQswCQYDVQQGEwJVUzEOMAwGA1UECBMFVGV4YXMxDzANBgNVBAcTBkF1c3RpbjEq\n"+
"MCgGA1UEChMhVGhlIFVuaXZlcnNpdHkgb2YgVGV4YXMgYXQgQXVzdGluMRMwEQYDVQQLEwpUb29s\n"+
"cyBUZWFtMQ8wDQYDVQQDEwZDbGllbnQwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAJ6PABjb\n"+
"zXUkgo29S4uv1Qz9reo1/tP4pkQTGAldSbtA4hVtA/3sjw2+u3kgxYruAi2cXV2k0RPZhsUZjlDk\n"+
"jMPb/dlY81bD8gqe3lu3ezugJrlArlpfWN6PlufbTjxHSqIA0XD9R5/ZECaUV9dD43K5KdWUCy99\n"+
"YKDiSwVPO9F5AgMBAAGjXTBbMB0GA1UdDgQWBBRkCCpscEXxXu8Ba67p6zdh13ypjzAfBgNVHSME\n"+
"GDAWgBR2RsZH2kSY782kBROo92FAWS6sADAJBgNVHRMEAjAAMA4GA1UdDwQHAwUBEiRIkDANBgkq\n"+
"hkiG9w0BAQQFAAOBgQCtV1NzpdVBs5vyb8yLXNA3hA1LsmE/2QanXG4T3UN93BI4HQzx0idnkN1Y\n"+
"0RAQ1rjGeQ1pk3l2DWsPi9mTkCGmYs/EMLkKOBee9ad3BIG6sKwXgbgLyNLgda+Y1bo+SIomq/a7\n"+
"yP92UHMFEegfS/ssECA+Q3hHuU6in3AqLfWH1w==\n"+
"-----END CERTIFICATE-----";
int startIndex = 0;
String cert = text.substring(startIndex,text.length());
byte[] certBytes = cert.getBytes();
InputStream in = new Base64InputStream(new ByteArrayInputStream(
certBytes), 0);
CertificateFactory certFact = CertificateFactory.getInstance ("X.509");
Certificate certGen = certFact.generateCertificate(in);
X509Certificate x509 = (X509Certificate) certGen;
Log.i("","certificate details:"+x509);
}
catch (Exception e)
{
Log.e("testapp", "exception: " + e.getMessage());
}
}
}
and I am getting android.util.BASE64DataException:bad base-64 at the foloowing line when I launced debugger:-
Certificate certGen = certFact.generateCertificate(in);
Seems like there is something wrong with Base64InputStream.Please help in rectifying the Exception.
Thanks in advance
No, nothing is wrong with Base64InputStream. When in doubt, you should suspect your own code of being incorrect rather than everyone else's.
What's wrong is that you're giving Base64InputStream data that ends with "-----END CERTIFICATE-----" after the padding part.
You should only be passing in the bit between "-----BEGIN CERTIFICATE-----" and "-----END CERTIFICATE-----".
It looks like you've started thinking about that already here:
int startIndex = 0;
String cert = text.substring(startIndex,text.length());
... but that code isn't going to do anything - when startIndex is 0, substring is going to return the whole string...
Personally I'd consider doing the Base64 conversion first using the Base64 class to convert the base64 part of the string (you still need to get the substring) to a byte[] and then create a ByteArrayInputStream around that.