<4.3

2015-01-12 4 views
3

에 대한 Android KeyStore 구현 Android 기기에서 KeyStore을 사용하여 KeyStore에 저장된 KeyPair의 AES 키를 암호화 할 계획입니다. 키 스토어 안드로이드 문서 :<4.3

https://developer.android.com/training/articles/keystore.html

인터넷을 검색 한 후 나는이에 수정했습니다 AOSP 예를 발견

/* 
* Copyright (C) 2013 The Android Open Source Project 
* 
* Licensed under the Apache License, Version 2.0 (the "License"); 
* you may not use this file except in compliance with the License. 
* You may obtain a copy of the License at 
* 
*  http://www.apache.org/licenses/LICENSE-2.0 
* 
* Unless required by applicable law or agreed to in writing, software 
* distributed under the License is distributed on an "AS IS" BASIS, 
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
* See the License for the specific language governing permissions and 
* limitations under the License. 
*/ 

import android.annotation.TargetApi; 
import android.content.Context; 
import android.os.Build; 
import android.security.KeyPairGeneratorSpec; 

import java.io.IOException; 
import java.math.BigInteger; 
import java.security.GeneralSecurityException; 
import java.security.KeyPair; 
import java.security.KeyPairGenerator; 
import java.security.KeyStore; 
import java.security.KeyStoreException; 
import java.security.NoSuchAlgorithmException; 
import java.security.UnrecoverableEntryException; 
import java.util.Calendar; 
import java.util.GregorianCalendar; 

import javax.crypto.Cipher; 
import javax.crypto.SecretKey; 
import javax.security.auth.x500.X500Principal; 


/** 
* Wraps {@link SecretKey} instances using a public/private key pair stored in 
* the platform {@link KeyStore}. This allows us to protect symmetric keys with 
* hardware-backed crypto, if provided by the device. 
* <p> 
* See <a href="http://en.wikipedia.org/wiki/Key_Wrap">key wrapping</a> for more 
* details. 
* <p> 
* Not inherently thread safe. 
* 
* Some explanations: 
* http://nelenkov.blogspot.nl/2013/08/credential-storage-enhancements-android-43.html 
*/ 
public class SecretKeyWrapper { 
    private final Cipher mCipher; 
    private final KeyPair mPair; 
    /** 
    * Create a wrapper using the public/private key pair with the given alias. 
    * If no pair with that alias exists, it will be generated. 
    */ 
    public SecretKeyWrapper(Context context, String alias) 
      throws GeneralSecurityException, IOException { 
     mCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); 
     final KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore"); 
     keyStore.load(null); 
     if (!keyStore.containsAlias(alias)) { 
      generateKeyPair(context, alias); 
     } 
     // Even if we just generated the key, always read it back to ensure we 
     // can read it successfully. 
     final KeyStore.PrivateKeyEntry entry = (KeyStore.PrivateKeyEntry) keyStore.getEntry(
       alias, null); 
     mPair = new KeyPair(entry.getCertificate().getPublicKey(), entry.getPrivateKey()); 
    } 
    @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2) 
    private static void generateKeyPair(Context context, String alias) 
      throws GeneralSecurityException { 
     final Calendar start = new GregorianCalendar(); 
     final Calendar end = new GregorianCalendar(); 
     end.add(Calendar.YEAR, 100); 
     final KeyPairGeneratorSpec spec = new KeyPairGeneratorSpec.Builder(context) 
       .setAlias(alias) 
       .setSubject(new X500Principal("CN=" + alias)) 
       .setSerialNumber(BigInteger.ONE) 
       .setStartDate(start.getTime()) 
       .setEndDate(end.getTime()) 
       .build(); 
     final KeyPairGenerator gen = KeyPairGenerator.getInstance("RSA", "AndroidKeyStore"); 
     gen.initialize(spec); 
     gen.generateKeyPair(); 
    } 

    /** 
    * Wrap a {@link SecretKey} using the public key assigned to this wrapper. 
    * Use {@link #unwrap(byte[])} to later recover the original 
    * {@link SecretKey}. 
    * 
    * @return a wrapped version of the given {@link SecretKey} that can be 
    *   safely stored on untrusted storage. 
    */ 
    public byte[] wrap(SecretKey key) throws GeneralSecurityException { 
     mCipher.init(Cipher.WRAP_MODE, mPair.getPublic()); 
     return mCipher.wrap(key); 
    } 
    /** 
    * Unwrap a {@link SecretKey} using the private key assigned to this 
    * wrapper. 
    * 
    * @param blob a wrapped {@link SecretKey} as previously returned by 
    *   {@link #wrap(SecretKey)}. 
    */ 
    public SecretKey unwrap(byte[] blob) throws GeneralSecurityException { 
     mCipher.init(Cipher.UNWRAP_MODE, mPair.getPrivate()); 
     return (SecretKey) mCipher.unwrap(blob, "AES", Cipher.SECRET_KEY); 
    } 
} 

wrapunwrap 내 경우에있는 SecretKey 관이 구현 AES 키.

그러나이 키 저장소는 4.3 이상에서만 지원됩니다. Jelly Bean 어노테이션을 참조하십시오.

제 질문에 이르기까지, 4.3 이하의 구현에 대한 가능성은 무엇입니까? 사전에

감사합니다,

답변

7

키 스토어는 1.6부터 사용할 수 있지만 이전 버전의 공식적인 API가 없습니다. 비공개 API를 통해 계속 사용할 수 있지만 다양한 문제가 발생할 수 있습니다.

는 참조 같은 블로그에서 확인할 수 있습니다 : 키 스토어 장치의 잠금 화면에서 독립적으로 잠금을 해제해야하기 때문

http://nelenkov.blogspot.com/2012/05/storing-application-secrets-in-androids.html

구현은 다소 까다로운을 끝낼 수 있습니다. 이전 버전에 대한 암호 기반 암호화를 고려하는 것이 더 좋을 수도 있습니다. 블로그에 대한 게시물이 있습니다.

0

Android KeyStore의 대칭 키 생성 및 저장은 Android 6.0 (API 레벨 23)부터 지원됩니다.

Android 키 저장소의 비대칭 키 생성 및 저장은 Android 4.3 (API 레벨 18)부터 지원됩니다.

자세한 내용은이 문서를 참조하십시오. http://developer.android.com/training/articles/keystore.html