安卓app作为应用侧访问华为物联网平台需要携带证书,Android的私钥和信任证书的格式必须是BKS格式的,可用openssl等工具进行证书格式转换(具体操作)转换完成后在src/mian目录下创建assets文件夹,不可直接创建文件夹(创建方式),并将bks证书(注意客户端和服务端证书都是bks类型)复制到文件夹内
public class SSLHelper{
private static final String TAG = "SSLHelper";
private static final String CLIENT_PRI_KEY = "client.bks";
private static final String TRUSTSTORE_PUB_KEY = "truststore.bks";
private static final String CLIENT_BKS_PW = "IoM@1234";//证书密钥
private static final String TRUSTSTORE_BKS_PW = "Huawei@123";//证书密钥
private static final String KEYSTORE_TYPE = "BKS";
private static final String PROTOCOL_TYPE = "TLS";
private static final String CERTIFICATE_STANDARD ="X509";
public static SSLSocketFactory getSSLCertificate(Context context){
SSLSocketFactory sslSocketFactory = null;
try {
//服务端需要验证的客户端证书,客户端的keystore(Keytool将密钥(key)和证书(certificates)存在一个称为keystore的文件中)
KeyStore keyStore = KeyStore.getInstance(KEYSTORE_TYPE);
//客户端信任服务端的证书
KeyStore trustStore = KeyStore.getInstance(KEYSTORE_TYPE);
//读取证书
InputStream ksIn = context.getAssets().open(CLIENT_PRI_KEY);
InputStream tsIn = context.getAssets().open(TRUSTSTORE_PUB_KEY);
//加载证书
keyStore.load(ksIn,CLIENT_BKS_PW.toCharArray());
trustStore.load(tsIn,TRUSTSTORE_BKS_PW.toCharArray());
ksIn.close();
tsIn.close();
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(CERTIFICATE_STANDARD);
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(CERTIFICATE_STANDARD);
trustManagerFactory.init(trustStore);
keyManagerFactory.init(keyStore,CLIENT_BKS_PW.toCharArray());
//初始化SSLContext
SSLContext sslContext = SSLContext.getInstance(PROTOCOL_TYPE);
sslContext.init(keyManagerFactory.getKeyManagers(),trustManagerFactory.getTrustManagers(),new java.security.SecureRandom());
sslSocketFactory = sslContext.getSocketFactory();
return sslSocketFactory;
} catch (KeyStoreException e) {
Log.d("KeyStoreException",e.toString());
e.printStackTrace();
} catch (IOException e) {
Log.d("IOException",e.toString());
e.printStackTrace();
} catch (CertificateException e) {
Log.d("CertificateException",e.toString());
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
Log.d("NoSuchAlgorithm",e.toString());
e.printStackTrace();
} catch (UnrecoverableKeyException e) {
Log.d("UnrecoverableKey",e.toString());
e.printStackTrace();
} catch (KeyManagementException e) {
Log.d("KeyManagement",e.toString());
e.printStackTrace();
}
return sslSocketFactory;
}
}
public class HttpsUtils {
public static class SSLParams{
public SSLSocketFactory sslSocketFactory;
public X509TrustManager trustManager;
}
public static SSLParams getSSLSocketFactory(InputStream[] certificates, InputStream bksFile, String password){
SSLParams sslParams = new SSLParams();
try {
TrustManager[] trustManagers = prepareTrustManager(certificates);
KeyManager[] keyManagers = prepareKeyManager(bksFile,password);
SSLContext sslContext = SSLContext.getInstance("TLS");
X509TrustManager trustManager = null;
if (trustManagers != null){
trustManager = new MyTrustManager(chooseTrustManager(trustManagers));
}else {
trustManager = new UnSafeTrustManager();
}
sslContext.init(keyManagers, new TrustManager[]{trustManager},null);
sslParams.sslSocketFactory = sslContext.getSocketFactory();
sslParams.trustManager = trustManager;
return sslParams;
} catch (NoSuchAlgorithmException e) {
throw new AssertionError(e);
} catch (KeyStoreException e) {
throw new AssertionError(e);
} catch (KeyManagementException e) {
throw new AssertionError(e);
}
}
public static class UnSafeHostnameVerifier implements HostnameVerifier{
@Override
public boolean verify(String s, SSLSession sslSession) {
return true;
}
}
public static class UnSafeTrustManager implements X509TrustManager{
@Override
public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[]{};
}
}
private static TrustManager[] prepareTrustManager(InputStream... certificates){
if (certificates == null || certificates.length <= 0){return null;}
try {
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null);
int index = 0;
for (InputStream certificate : certificates){
String certificateAlias = Integer.toString(index++);
keyStore.setCertificateEntry(certificateAlias,certificateFactory.generateCertificate(certificate));
if (certificate != null){
certificate.close();
}
}
TrustManagerFactory trustManagerFactory = null;
trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(keyStore);
TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
return trustManagers;
} catch (CertificateException e) {
e.printStackTrace();
} catch (KeyStoreException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
private static KeyManager[] prepareKeyManager(InputStream bksFile, String password){
if (bksFile == null || password == null){return null;}
try {
KeyStore clientKeyStore = KeyStore.getInstance("BKS");
clientKeyStore.load(bksFile,password.toCharArray());
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(clientKeyStore,password.toCharArray());
return keyManagerFactory.getKeyManagers();
} catch (KeyStoreException e) {
e.printStackTrace();
} catch (CertificateException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (UnrecoverableKeyException e) {
e.printStackTrace();
}
return null;
}
private static X509TrustManager chooseTrustManager(TrustManager[] trustManagers){
for (TrustManager trustManager : trustManagers){
if (trustManager instanceof X509TrustManager){
return (X509TrustManager) trustManager;
}
}
return null;
}
private static class MyTrustManager implements X509TrustManager{
private X509TrustManager defaultTrustManager;
private X509TrustManager localTrustManager;
public MyTrustManager(X509TrustManager localTrustManager) throws NoSuchAlgorithmException, KeyStoreException {
TrustManagerFactory var4 = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
var4.init((KeyStore) null);
defaultTrustManager = chooseTrustManager(var4.getTrustManagers());
this.localTrustManager = localTrustManager;
}
@Override
public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
try {
defaultTrustManager.checkServerTrusted(x509Certificates,s);
} catch (CertificateException e) {
localTrustManager.checkServerTrusted(x509Certificates,s);
}
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
}
}
本案例需要post的数据较为复杂,可根据自身情况删减(retrofit2的相关资料)
public class MainActivity extends AppCompatActivity {
private Button btn,btnOpen;
private TextView tv;
public static final MediaType JSON = MediaType.parse("application/json;charset=utf-8");
int flag = 0;
public interface ApiLogin{
@POST("***")
@FormUrlEncoded
Call<ResponseBody> testFromUrlEncoded(@Field("appId") String appID,@Field("secret") String secret);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = findViewById(R.id.tv);
btn = findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
login();
}
});
btnOpen = findViewById(R.id.btn_open);
btnOpen.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
change();
}
});
}
public void login(){
//创建日志拦截器,用于日志打印
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
//调用ssl建立连接
OkHttpClient httpClient = new OkHttpClient().newBuilder()
.addInterceptor(interceptor)
.sslSocketFactory(SSLHelper.getSSLCertificate(this),new HttpsUtils.UnSafeTrustManager())
.hostnameVerifier(new HttpsUtils.UnSafeHostnameVerifier()).build();
String baseUrl = "***";//url
String appId = "***";//需要post的表单数据
String secret = "***";//需要post的表单数据
Retrofit retrofit = new Retrofit.Builder().baseUrl(baseUrl).client(httpClient)
.addConverterFactory(ScalarsConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create()).build();
final ApiLogin request = retrofit.create(ApiLogin.class);
Call<ResponseBody> call = request.testFromUrlEncoded(appId,secret);//绑定表单数据
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
final String content;
try {
//解析请求返回的json数据
content = response.body().string();
Log.d("response",content);
Gson gson = new Gson();
loginBean loginBean = gson.fromJson(content, com.example.hworder.json.loginBean.class);
final String accessToken = loginBean.getAccessToken();
Log.d("accessToken",accessToken);
runOnUiThread(new Runnable() {
@Override
public void run() {
tv.setText(accessToken);//
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Log.d("fail",t.toString());
}
});
}
public void change(){
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
final String accessToken = (String) tv.getText();
Log.d("getAccessToken",accessToken);
String url = "***";
Map changeMap = changeBody(flag);//post发送的json数据
Gson gson = new Gson();
String changeStr = gson.toJson(changeMap);//将json数据转换成字符串
Log.d("changeStr",changeStr);
OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder();
clientBuilder.addInterceptor(new Interceptor() {
@Override
public okhttp3.Response intercept(Chain chain) throws IOException {
Request original = chain.request();
//设置请求头
Request request = original.newBuilder()
.header("***","***")
.header("***","***")
.header("Content-Type","application/json").build();
return chain.proceed(request);
}
});
OkHttpClient client = clientBuilder.addInterceptor(interceptor)
.sslSocketFactory(SSLHelper.getSSLCertificate(this),new HttpsUtils.UnSafeTrustManager())
.hostnameVerifier(new HttpsUtils.UnSafeHostnameVerifier())
.build();
RequestBody requestBody = RequestBody.create(JSON,changeStr);//根据json数据转化的字符串创建请求体
Request request = new Request.Builder().post(requestBody)
.url("***").build();
client.newCall(request).enqueue(new okhttp3.Callback() {
@Override
public void onFailure(okhttp3.Call call, final IOException e) {
Log.d("changeFail",e.toString());
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(getBaseContext(),e.toString(),Toast.LENGTH_SHORT).show();
}
});
}
@Override
public void onResponse(okhttp3.Call call, okhttp3.Response response) throws IOException {
final String resp = response.toString();
Log.d("changeRes",resp);
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(getBaseContext(),resp,Toast.LENGTH_SHORT).show();
}
});
}
});
}
private Map changeBody(int flag){
Map header = new HashMap<>();
Map body = new HashMap<>();
Map change = new HashMap<>();
header.put("mode","ACK");
header.put("from","/cloud/communion");
header.put("method","SET");
if (flag % 2 == 0){
body.put("value",0);
}else {
body.put("value",1);
}
flag++;
this.flag = flag;
change.put("header",header);
change.put("body",body);
return change;
}