0

クライアント側のSSL認証を行う必要があるRSSフィードリーダーを構築しようとしています。

私は証明書を持っているか、少なくとも持っていると思います。ただし、認証のために証明書をサーバーに送信するようにsslトンネルを設定する方法がわかりません。

これが私がこれまでに持っているものです:

public class Authenticator extends Activity {

PrivateKey privateKey = null;
String SavedAlias = "";
private static final String TAG = "AUTHENTICATOR.CLASS";
final HttpParams httpParams = new BasicHttpParams();
private KeyStore mKeyStore = KeyStore.getInstance();

public Handler mHandler = new Handler(Looper.getMainLooper());

public void run()
{
   mHandler.post(new Runnable() {
      public void run() {
          new AliasLoader().execute();
      }
   });
}


@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    getCertificates("TEST");
}

public class AliasLoader extends AsyncTask<Void, Void, X509Certificate[]> 
{
    X509Certificate[] chain = null;

    @Override protected X509Certificate[] doInBackground(Void... params) {
        android.os.Debug.waitForDebugger();

        if(!SavedAlias.isEmpty())
        {
                try {
                    chain = KeyChain.getCertificateChain(getApplicationContext(),SavedAlias);
                } catch (Exception e) {
                    Log.e(TAG, e.getMessage());
                }
        }
        else
        {
            this.cancel(true);
        }

        return chain;
    }

    @Override 
    protected void onPostExecute(X509Certificate[] chain) 
    {

        if(chain != null)
        {
            Toast.makeText(getApplicationContext(), "YAY, Certificate is not empty", Toast.LENGTH_LONG).show();
        }
        else
        {
            Toast.makeText(getApplicationContext(), "Certificate is Empty", Toast.LENGTH_LONG).show();
        }

        /*
        if (privateKey != null) {
            Signature signature = null;
            try {
                signature = Signature.getInstance("SHA1withRSA");
            } catch (NoSuchAlgorithmException e) {
                Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_LONG).show();
            }
            try {
                signature.initSign(privateKey);
            } catch (InvalidKeyException e) {
                Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_LONG).show();
            }
        }
        */
    }
}

public void getCertificates(String Host)
{
    KeyChainAliasCallback callBack = new KeyChainAliasCallback() {

        @Override
        public void alias(String alias) {               
            if (alias != null) 
            {
                Looper.prepare();
                saveAlias(alias);
                run();
                Looper.loop();
            }
        }
    };

    KeyChain.choosePrivateKeyAlias(this, callBack,
    new String[] {"RSA", "DSA"}, // List of acceptable key types. null for any
    null,                        // issuer, null for any
    null,      // host name of server requesting the cert, null if unavailable
    443,                         // port of server requesting the cert, -1 if unavailable
    null);                       // alias to preselect, null if unavailable
}

public void saveAlias(String alias)
{
    SavedAlias = alias;
}
}

4.0は実装が古いバージョンとは異なるように見えるため、これまでに認証を行ったことがなく、Android 4.0でこのトピックについて何かを見つけるのは難しいと感じたため、これを行う方法についてのヘルプをいただければ幸いです。

4

2 に答える 2

2

証明書チェーンと秘密鍵を取得して、一時的なメモリ内に保存できるはずですKeyStore

String alias = "test";
KeyStore memoryKeyStore = KeyStore.getInstance("BKS");
memoryKeyStore.load(null);
X509Certificate[] chain = KeyChain.getCertificateChain(getApplicationContext(),alias);
PrivateKey key = KeyChain.getPrivateKey(getApplicationContext(),alias);
memoryKeyStore.setKeyEntry(alias, key.getEncoded(), chain);

その後、このキーストアを使用してSSLContextインスタンスを初期化できます。

警告:サンプルコードには、X509TrustManagerサーバー証明書の検証を実行しない実装が含まれていることに注意してください。使わない方がいいです。

于 2012-07-23T12:54:30.297 に答える
0

提案されたソリューションは4.1以降では機能しません。そこでは秘密鍵はエクスポートできず、メモリ内の鍵ストアに置くことはできません。 4.1で行う方法については、ApacheクライアントとKeyChainAPIを使用してAndroid4.1からクライアント証明書認証を行う方法を確認してください。

于 2012-11-28T13:54:57.033 に答える