I'm new to reverse engineering, I've never developed an android application before and I'm trying to extract from an android application the certificate it's using to authenticate to the server.
One of the answers to this post mentions that extracting a private key from an apk file is indeed a possible thing.
This post says that unlesss we have the original keystore file of the application we won't be able to extract the private key. Is it possible to get the original keystore file? Most of the posts seem to agree on the fact that this is impossible!
I've decompiled the application I'm interested in, and I retrieved the CERT.RSA from it, but I don't know if this can help me extract the certificate and the private key from the application. What can we do with the CERT.RSA file anyways?
I know that an android application is accessible to anyone from the google play store, so if what I'm trying to do is possible anyone could extract the certificate and private key and hack any application, but I just want to know if there were some specific tips/hacks, a good tutorial or just an indication of where to start off?
Here is the pcap I get when I send a request to the server that the app communicates with:
10.0.0.1 is the client IP address and 192.168.10.211 is the server's IP address, and we can see that the client is sending 2 certificates to the server during the handshake session, so where do these certificates come from? are they hardcoded in the application?
UPDATE
As you can see on the pcap file, the client does send a certificate to the server during the handshake session, so I spent the last few days trying to retrieve it and use it to forward a request to my server.
I've finally managed to retrieve the certificate, the problem is I don't know how can I use it to get the job done.
Here is exactly what I did:
This is the java code that logs the certificate and the password that the client uses during the handshake protocol:
public static native byte[] getCplusPKCS12Cert();
public static native byte[] getCplusPKCS12Pass();
static {
System.loadLibrary("cplusnative");
}
public static SSLSocketFactory a() {
SSLSocketFactory sSLSocketFactory = null;
SSLContext instance = SSLContext.getInstance("TLS");
byte[] cplusPKCS12Cert = getCplusPKCS12Cert();
String s = Base64.getEncoder().encodeToString(cplusPKCS12Cert);
Log.d('certificate',s);
byte[] cplusPKCS12Pass = getCplusPKCS12Pass();
Log.d('password',cplusPKCS12Pass);
return sSLSocketFactory;
}
This allows me to get the certificate which is a PKCS12 certificate that's secured with a password which is logged to the terminal too when I launch:$ adb logcat
This is what I get:
certificate:
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
wCFEL+hYAgIIAA==
password: S0xXYUY4QWtSdW9mYW5VAA==
I put the certificate in a .p12 file, but I can't open it.
To overcome this issue I print the certificate to android storage: storage/emulated/0/output.p12 which created a file containing hexadecimal data. When I use this file to forward a request to my server using python:
$ python3
> from requests_pkcs12 import get
> r = get(url, pkcs12_filename='theOutput.p12', pkcs12_password='S0xXYUY4QWtSdW9mYW5VAA==')
I get the following error:
Error: [('asn1 encoding routines', 'ASN1_get_object', 'header too long')]
I feel that I have all the pieces of the puzzle and I only need to put them together, so my question is: How can I use the resources (certificate/password) I have retrieved to forward requests to the server?
Thank you.
Related
I want to create a custom OpenVpn For Android client that satisfies my requirements. In typical mode , clients have a configuration file (.ovpn file) that they use to connect to OpenVpn server. Authentication procedure can be either username/password or certificate-based. But I want key generation procedure being done in client(mobile) not in server side and private key remains completely private and server doesn't access to it.
I mean changing code of openvpn for android client to generate key pair in TEE (trusted execution environment) of mobile and then creating CSR (Certificate Signing Request) and then sending CSR file to Openvpn server and server signs CSR file and create CRT (Certificate file) and send back to client. Client stores CRT file in TEE and communicate to OpenVpn server using Private key/Certificate in next times.
Is this scenario possible? Anyone has any idea about implementing this feature?
I mean changing code of openvpn for android client to generate key
pair in TEE (trusted execution environment) of mobile
This can easily be done in the TEE. Assuming you are using OPTEE-OS for example, then you can use the Global Platform API to generate a key pair from your Trusted Application. If you are using another TEE-OS this will of course be possible assuming they offer the functionality.
and then creating CSR (Certificate Signing Request)
Depending on the support offered by the TEE, this is also possible. OPTEE-OS has support for X509 certificates using mbedTLS.
Or, your Client application can ask the Trusted Application to get the public key under the PEM format and call openssl, mbedTLS or any other library to create the CSR.
and then sending CSR file to Openvpn server and server signs CSR file
and create CRT (Certificate file) and send back to client. Client
stores CRT file in TEE and communicate to OpenVpn server using Private
key/Certificate in next times.
Your client application would have to send the certificate request and inject the signed certificate to the Trusted Application, which then will have to check if the private key and public key of the certificate matches.
This is a possible scenario, however OpenVpn will need to have a way to verify the client, and thus, will have to call a function verify/certify which will use the stored certificate and private key in the TEE.
i need to get echo value i.e (yes or no) from php file to myresulttextview but unable to retrieve it says error :"com.android.volley.NoConnectionError: javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found. "
val barcode = data.getParcelableExtra<Barcode>(BarcodeCaptureActivity.BarcodeObject)
val p = barcode.cornerPoints
var m = barcode.displayValue.toString().trim()
val jsonobj=JSONObject()
jsonobj.put("email",m)
val url="https://192.168.2.11/verf1.php"
val que=Volley.newRequestQueue(this#MainActivity)
val req=JsonObjectRequest(Request.Method.POST,url,jsonobj,Response.Listener {
response ->mResultTextView.setText(response.toString())
},Response.ErrorListener {
response ->mResultTextView.setText(response.toString())
})
que.add(req)
my php file
<?php
require "conn.php";
$user_name=false;
if(isset($_POST["email"])){
$user_name = $_POST["email"];
}
$mysql_qry="select * from exitpass where email like '%".$user_name."%'";
$result=mysqli_query($conn,$mysql_qry);
if(mysqli_num_rows($result)>0)
{
echo"yes";
}
else{
echo"no";}
?>
The error is related to the TLS/SSL certificate associated with your 192.168.2.11 web server. There are a few different ways to solve this problem depending on what your setup is like.
If you have no cert installed on your web server then replace https with http to send over an unencrypted channel.
val url="http://192.168.2.11/verf1.php"
If the web server does have a cert installed then you could have a few issues. Common issues related to the stack trace are invalid certs, using the wrong (or no) domain name, wrong Java code for the encryption type and Java version, issue somewhere in the trust chain, expired cert, etc.
In summary, I believe you simply need to send over http, but if that doesn't work, you should troubleshoot it in this order.
Change the IP to the domain name associated with your cert
Verify you can access your resource in the browser and that the certificate is not expired
Figure out what type of encryption you are using (TLS 1.1, TLS 1.2, etc) and what Java you are using (1.6 or 1.7). There is a key difference between Java 6 and Java 7 as it relates to accessing TLS encrypted resources and I explain it in my highest rated post (as a reference).
If all else fails you will likely need to manually install the certificate in Androids JVM trust store. I believe you can do this from most GUIs and definitely from the terminal if you have access. You shouldn't have to do this, but sometimes you are forced to if the certificate chain breaks. It might not even be your cert causing the issue, it can be any cert in your trust chain.
Please let me know if the initial suggestion works. If it doesn't work please provide the public cert here ( or just the domain name and I will pull it down) and your Java version and I can better assist.
I have a custom SSL Root CA for the web and I want to be able to install it on android devices. If I download it it says "No certificate to install". How can I configure the certificate to work using openSSL or another tool? I have done some googling and some sites say that I should covert it to a .pfx but this involves giving the user my private key and ruining the security.
If you want to add your certificate to Android KeyChain (it is possible since ICS) you need to provide X509Certificate (.crt, .pem, etc) or PKCS12 (.pfx) file.
You have to call install intent from KeyChain class.
According to documentation: http://developer.android.com/reference/android/security/KeyChain.html#createInstallIntent()
Returns an Intent that can be used for credential installation. The
intent may be used without any extras, in which case the user will be
able to install credentials from their own source.
Alternatively, EXTRA_CERTIFICATE or EXTRA_PKCS12 maybe used to specify
the bytes of an X.509 certificate or a PKCS#12 key store for
installation. These extras may be combined with EXTRA_NAME to provide
a default alias name for credentials being installed.
When used with startActivityForResult(Intent, int), RESULT_OK will be
returned if a credential was successfully installed, otherwise
RESULT_CANCELED will be returned.
However
In my opinion what you really want to do is to include your X509Certificate along with your application so you can estabilish secure SSL connection without user knowledge which will work on all devices.
In order to do that, you will have to create put your X509Certificate in application (as PEM string, .crt file .der file or inside BouncyCastle KeyStore) and initialize SSLContext with it. After you do that you can get SSLSocketFactory which you can use with you http client.
More information about that:
https://developer.android.com/training/articles/security-ssl.html
I'm trying to make a connection to an LDAP server in my Android app, and am using the UnboundID SDK. Recently, a change was made from unsecured to secured LDAP, and I have to change the app accordingly. I have been given the SSL certificates file to validate against. I've already used the file to make a keystore as described here. I've got this keystore file in the assets folder of my app, and am pulling from that. The code below does not currently work, and throws the exception:
LDAPException(resultCode=01 (connect error), errorMessage=('An error occurred while attempting to connect to server place.myserver.com:636: javax.net.ssl.SSLHandShakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found
// code from above link
AssetManager assetManager = getApplicationContext().getAssets();
InputStream keyStoreInputStream = assetManager.open("yourapp.store");
KeyStore trustStore = KeyStore.getInstance("BKS");
trustStore.load(keyStoreInputStream, "myPassword".toCharArray());
TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509");
tmf.init(trustStore);
// my code
SSLUtil sslUtil = new SSLUtil(tmf.getTrustManagers());
LDAPConnection connection = new LDAPConnection(sslUtil.createSSLSocketFactory());
connection.connect("place.myserver.com", 636);
However, the code segment:
SSLUtil sslUtil = new SSLUtil(new TrustAllTrustManager());
LDAPConnection connection = new LDAPConnection(sslUtil.createSSLSocketFactory());
connection.connect("place.myserver.com", 636);
does work (although I was informed by the higher-ups that this would be insecure).
I'm not quite sure as to what exactly I'm doing wrong here, so any help would be appreciated. Also, if there is a better way of accomplishing this than what I'm attempting to do above, feel free to let me know :) I would like to stick with the UnboundID library though, since the rest of the code is already written using that as well, and everything works if I use the TrustAllTrustManager.
It's true that the trust all trust manager isn't secure. It's convenient for testing purposes, but it will allow a bad guy to set up his own server with a certificate he generates for himself and use it to impersonate the real server, or to operate as a man in the middle, intercepting and potentially alerting any communication between the client and the real server. With a more strict trust manager in place, the client should reject the bogus certificate that the fake server will present.
Unfortunately, though, it looks like the trust manager you're trying to use in this case doesn't like the certificate that your server is presenting to it. Because the trust all trust manager allows you to establish the connection, that means that your server does have a certificate and is capable of performing SSL communication, but there's something about that certificate that your trust manager doesn't like. It's almost certainly not an issue with the LDAP SDK, since the same problem should arise with any other LDAP API if you're using the same trust store.
If you look at the result, it has a message of "Trust anchor for certification path not found". This implies that neither the certificate the server is using nor those of any of its issuers was found in the trust store. You'll need to import the server certificate (or the certificate of one of its issuers) into the trust store that you're using. It sounds like you've tried to do that, but since it's not working then something must not be quite right with the way it was done. I'd recommend working wit the directory server administrator to ensure that you're trying to import the right certificate based on the server configuration.
I want to establish an ssl communication to the server from my android client.
this is what I've done so far:
1 Created a a pair of public private keys using java keytool genkey(and in the process created a self signed certificate)
2. Exported the public key and imported the public key in to another keystore(called customkeystore)
Now I want to use this customkeystore file as my truststore. Where should I place this file in my android client and how to make it aware of the path of this trustore and access it.
Don't know Android but I would imagine that you just load your keystore like in any Java application.
This is what happens here SSL through Android and here SSL Verification Android