- 안드로이드는 BKS 방식으로 만들어야 된다. JKS는 안됨
- Download bouncycastle JAR from http://repo2.maven.org/maven2/org/bouncycastle/bcprov-ext-jdk15on/1.46/bcprov-ext-jdk15on-1.46.jar or take it from the "doc" folder.
- Configure BouncyCastle for PC using one of the below methods.
- Adding the BC Provider Statically (Recommended)
- Copy the bcprov-ext-jdk15on-1.46.jar to each
- D:\tools\jdk1.5.0_09\jre\lib\ext (JDK (bundled JRE)
- D:\tools\jre1.5.0_09\lib\ext (JRE)
- C:\ (location to be used in env variable)
- Modify the java.security file under
- D:\tools\jdk1.5.0_09\jre\lib\security
- D:\tools\jre1.5.0_09\lib\security
- and add the following entry
- security.provider.7=org.bouncycastle.jce.provider.BouncyCastleProvider
- Add the following environment variable in "User Variables" section
- CLASSPATH=%CLASSPATH%;c:\bcprov-ext-jdk15on-1.46.jar
- Copy the bcprov-ext-jdk15on-1.46.jar to each
- Add bcprov-ext-jdk15on-1.46.jar to CLASSPATH of your project and Add the following line in your code
- Security.addProvider(new BouncyCastleProvider());
- Adding the BC Provider Statically (Recommended)
- Generate the Keystore using Bouncy Castle
- Run the following command
- keytool -genkey -alias myproject -keystore C:/myproject.keystore -storepass myproject -storetype BKS -provider org.bouncycastle.jce.provider.BouncyCastleProvider
- This generates the file C:\myproject.keystore
- Run the following command to check if it is properly generated or not
- keytool -list -keystore C:\myproject.keystore -storetype BKS
- Run the following command
Configure BouncyCastle for TOMCAT
Open D:\tools\apache-tomcat-6.0.35\conf\server.xml and add the following entry
- <Connector port="8443" keystorePass="myproject" alias="myproject" keystore="c:/myproject.keystore" keystoreType="BKS" SSLEnabled="true" clientAuth="false" protocol="HTTP/1.1" scheme="https" secure="true" sslProtocol="TLS" sslImplementationName="org.bouncycastle.jce.provider.BouncyCastleProvider"/>
Restart the server after these changes.
- Configure BouncyCastle for Android Client
- No need to configure since Android supports Bouncy Castle Version 1.46 internally in the provided "android.jar".
- Just implement your version of HTTP Client (MyHttpClient.java can be found below) and set the following in code
- SSLSocketFactory.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
- If you don't do this, it gives an exception as below
- javax.net.ssl.SSLException: hostname in certificate didn't match: <192.168.104.66> !=
- In production mode, change the above code to
- SSLSocketFactory.setHostnameVerifier(SSLSocketFactory.STRICT_HOSTNAME_VERIFIER);
MyHttpClient.java
package com.arisglobal.aglite.network;
import java.io.InputStream;
import java.security.KeyStore;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.SingleClientConnManager;
import com.arisglobal.aglite.activity.R;
import android.content.Context;
public class MyHttpClient extends DefaultHttpClient {
final Context context;
public MyHttpClient(Context context) {
this.context = context;
}
@Override
protected ClientConnectionManager createClientConnectionManager() {
SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
// Register for port 443 our SSLSocketFactory with our keystore to the ConnectionManager
registry.register(new Scheme("https", newSslSocketFactory(), 443));
return new SingleClientConnManager(getParams(), registry);
}
private SSLSocketFactory newSslSocketFactory() {
try {
// Get an instance of the Bouncy Castle KeyStore format
KeyStore trusted = KeyStore.getInstance("BKS");
// Get the raw resource, which contains the keystore with your trusted certificates (root and any intermediate certs)
InputStream in = context.getResources().openRawResource(R.raw.aglite);
try {
// Initialize the keystore with the provided trusted certificates.
// Also provide the password of the keystore
trusted.load(in, "aglite".toCharArray());
} finally {
in.close();
}
// Pass the keystore to the SSLSocketFactory. The factory is responsible for the verification of the server certificate.
SSLSocketFactory sf = new SSLSocketFactory(trusted);
// Hostname verification from certificate
// http://hc.apache.org/httpcomponents-client-ga/tutorial/html/connmgmt.html#d4e506
sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
return sf;
} catch (Exception e) {
throw new AssertionError(e);
}
}
}
How to invoke the above code in your Activity class:
DefaultHttpClient client = new MyHttpClient(getApplicationContext());
HttpResponse response = client.execute(...);
2. keystore 파일 생성
1) http://bouncycastle.org/latest_releases.html 에서 설치된 JDK에 해당하는 bcprov-jdkXX-XXX.jar 파일을 다운 로드 받는다. Posted by Brent
2) *.bks 파일을 생성한다.
keytool -importcert -v -trustcacerts -file "brent.cer" -alias brentCA -keystore "brent.bks" -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath "bcprov-jdk16-145.jar" -storetype BKS -storepass "password"
Posted by Brent
keytool -list -keystore "brent.bks" -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath "bcprov-jdk16-145.jar" -storetype BKS -storepass "password"
** 자세한 의미는 인터넷을 찾아보자..
Posted by Brent
3. *.bks 파일을 /res 폴더 밑에 적당히 집어 넣어 준다.(그래야 R.class에 자동으로 등록 되어 사용 할 수 있다)
Posted by Brent
4. 다음과 같이 즐겁게 사용하자!
char[] passphrase = "password".toCharArray();
KeyStore keystore = KeyStore.getInstance("BKS");
keystore.load(activity.getResources().openRawResource(R.raw.brent), passphrase);
Posted by Brent
TrustManagerFactory tmf = TrustManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
tmf.init(keystore);
Posted by Brent
SSLContext context = SSLContext.getInstance("TLS");
TrustManager[] trustManagers = tmf.getTrustManagers();
context.init(null, trustManagers, null);
Posted by Brent
SSLSocketFactory sf = context.getSocketFactory();
Socket mSocket = sf.createSocket(ip, port);