1

ICS Android は、KeyChain API を介して、システム キーストアと信頼できる CA への統合アクセスをサポートしているためです。

とてもいいのですが、このソースからの秘密鍵をクライアント証明書認証に使用しようとすると、次のような問題が発生します。

ここでいくつかの回答を確認しましたが、見つかった最高のものは次のとおりです。Android 4.0 SSL認証

これは 4.0 を参照し、次のコーディングを提供します。

更新 - このコーディングは間違っています - 4.1 以降では機能しません

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);

ただし、これは 4.1 では機能しません。これは、getEncoded() メソッドが呼び出されたときに KeyChain.getPrivateKey() によって返される PrivateKey オブジェクトが null を返し、KeyStore を初期化できないためです。

4.1でこれを行う他の方法はありますか?

更新 - KeyStore と KeyStoreSpi の独自の実装を定義する正しい方法はこちら KeyStore と KeyStoreSpi のサンプル実装は次のとおりです。

KeyStoreSpi の実装:

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.Key;
import java.security.KeyStoreException;
import java.security.KeyStoreSpi;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.Enumeration;
import java.util.List;

import java.security.PrivateKey;

public class KeyChainProxy extends KeyStoreSpi {


  private String alias = null;
  private PrivateKey privateKey = null;
  private Certificate[] certChain = null;

  public KeyChainProxy(String alias, PrivateKey privateKey, Certificate[] certChain) {
    this.alias = alias;
    this.privateKey = privateKey;
    this.certChain = certChain;
  }

  @Override
  public Key engineGetKey(String alias, char[] password) throws NoSuchAlgorithmException, UnrecoverableKeyException {
    return privateKey;
  }

  @Override
  public Certificate[] engineGetCertificateChain(String alias) {
    return certChain;
  }

  @Override
  public Certificate engineGetCertificate(String alias) {
    return certChain[0];
  }

  @Override
  public Date engineGetCreationDate(String alias) {
    return new Date();
  }

  @Override
  public void engineSetKeyEntry(String alias, Key key, char[] password, Certificate[] chain) throws KeyStoreException {
    throw new KeyStoreException("Not Implemented");

  }

  @Override
  public void engineSetKeyEntry(String alias, byte[] key, Certificate[] chain) throws KeyStoreException {
    throw new KeyStoreException("Not Implemented");

  }

  @Override
  public void engineSetCertificateEntry(String alias, Certificate cert) throws KeyStoreException {
    throw new KeyStoreException("Not Implemented");

  }

  @Override
  public void engineDeleteEntry(String alias) throws KeyStoreException {
    throw new KeyStoreException("Not Implemented");

  }

  @Override
  public Enumeration<String> engineAliases() {
    List<String> list = new ArrayList<String>();
    list.add(alias);
    return Collections.enumeration(list);
  }

  @Override
  public boolean engineContainsAlias(String alias) {
    return alias != null && alias.equals(this.alias);
  }

  @Override
  public int engineSize() {
    return 1;
  }

  @Override
  public boolean engineIsKeyEntry(String alias) {
    return true;
  }

  @Override
  public boolean engineIsCertificateEntry(String alias) {
    return false;
  }

  @Override
  public String engineGetCertificateAlias(Certificate cert) {
    return null;
  }

  @Override
  public void engineStore(OutputStream stream, char[] password) throws IOException, NoSuchAlgorithmException, CertificateException {

  }

  @Override
  public void engineLoad(InputStream stream, char[] password) throws IOException, NoSuchAlgorithmException, CertificateException {

  }

}

キーストアの実装:

import java.security.KeyStore;
import java.security.KeyStoreSpi;
import java.security.Provider;

public class KeyChainKeystore extends KeyStore {

  public KeyChainKeystore(KeyStoreSpi keyStoreSpi, Provider provider, String type) {
    super(keyStoreSpi, provider, type);
    try {
      load(null, null);
    } catch (Exception e) {
      // ignore - our spi doesn't do anything
    }
  }

}

ありがとうございました

ヴァシル

4

1 に答える 1

3

KeyChain は、秘密鍵を保護するように設計されています。

したがって、秘密鍵への参照を取得し、その秘密鍵をアプリ内で認証、暗号化などに使用できますが、実際の秘密鍵データにはアクセスできません。

したがって、秘密鍵をエクスポートすることはできません-これはあなたがやろうとしていることです.

于 2012-11-14T15:28:11.107 に答える