Back to project page androidkeystore.
The source code is released under:
Apache License
If you think the Android project androidkeystore listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.
/* * Copyright 2013 The Android Open Source Project */*w w w . ja v a 2 s .com*/ * 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. */ package com.example.keystore; import java.io.IOException; import java.math.BigInteger; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Signature; import java.security.SignatureException; import java.security.UnrecoverableEntryException; import java.security.cert.CertificateException; import java.util.Calendar; import java.util.GregorianCalendar; import javax.security.auth.x500.X500Principal; import android.content.Context; import android.security.KeyPairGeneratorSpec; import android.util.Base64; import com.example.keystore.common.SecurityConstants; import com.example.keystore.common.logger.Log; public class KeyStoreHelper { public static final String TAG = "KeyStoreHelper"; // You can store multiple key pairs in the Key Store. The string used to // refer to the Key you // want to store, or later pull, is referred to as an "alias" in this case, // because calling it // a key, when you use it to retrieve a key, would just be irritating. private String mAlias = null; /** * Creates a public and private key and stores it using the Android Key * Store, so that only this application will be able to access the keys. */ public void createKeys(Context context) throws NoSuchProviderException, NoSuchAlgorithmException, InvalidAlgorithmParameterException { // Create a start and end time, for the validity range of the key pair // that's about to be // generated. Calendar start = new GregorianCalendar(); Calendar end = new GregorianCalendar(); end.add(1, Calendar.YEAR); // The KeyPairGeneratorSpec object is how parameters for your key pair // are passed // to the KeyPairGenerator. For a fun home game, count how many classes // in this sample // start with the phrase "KeyPair". KeyPairGeneratorSpec spec = new KeyPairGeneratorSpec.Builder(context) // You'll use the alias later to retrieve the key. It's a key // for the key! .setAlias(mAlias) // The subject used for the self-signed certificate of the // generated pair .setSubject(new X500Principal("CN=" + mAlias)) // The serial number used for the self-signed certificate of the // generated pair. .setSerialNumber(BigInteger.valueOf(1337)) // Date range of validity for the generated pair. .setStartDate(start.getTime()).setEndDate(end.getTime()) .build(); // Initialize a KeyPair generator using the the intended algorithm (in // this example, RSA // and the KeyStore. This example uses the AndroidKeyStore. KeyPairGenerator kpGenerator = KeyPairGenerator.getInstance( SecurityConstants.TYPE_RSA, SecurityConstants.KEYSTORE_PROVIDER_ANDROID_KEYSTORE); kpGenerator.initialize(spec); KeyPair kp = kpGenerator.generateKeyPair(); Log.d(TAG, "Public Key is: " + kp.getPublic().toString()); } /** * Signs the data using the key pair stored in the Android Key Store. This * signature can be used with the data later to verify it was signed by this * application. * * @return A string encoding of the data signature generated */ public String signData(String inputStr) throws KeyStoreException, UnrecoverableEntryException, NoSuchAlgorithmException, InvalidKeyException, SignatureException, IOException, CertificateException { byte[] data = inputStr.getBytes(); KeyStore ks = KeyStore .getInstance(SecurityConstants.KEYSTORE_PROVIDER_ANDROID_KEYSTORE); // Weird artifact of Java API. If you don't have an InputStream to load, // you still need // to call "load", or it'll crash. ks.load(null); // Load the key pair from the Android Key Store KeyStore.Entry entry = ks.getEntry(mAlias, null); /* * If the entry is null, keys were never stored under this alias. Debug * steps in this situation would be: -Check the list of aliases by * iterating over Keystore.aliases(), be sure the alias exists. -If * that's empty, verify they were both stored and pulled from the same * keystore "AndroidKeyStore" */ if (entry == null) { Log.w(TAG, "No key found under alias: " + mAlias); Log.w(TAG, "Exiting signData()..."); return null; } /* * If entry is not a KeyStore.PrivateKeyEntry, it might have gotten * stored in a previous iteration of your application that was using * some other mechanism, or been overwritten by something else using the * same keystore with the same alias. You can determine the type using * entry.getClass() and debug from there. */ if (!(entry instanceof KeyStore.PrivateKeyEntry)) { Log.w(TAG, "Not an instance of a PrivateKeyEntry"); Log.w(TAG, "Exiting signData()..."); return null; } // This class doesn't actually represent the signature, // just the engine for creating/verifying signatures, using // the specified algorithm. Signature s = Signature .getInstance(SecurityConstants.SIGNATURE_SHA256withRSA); // Initialize Signature using specified private key s.initSign(((KeyStore.PrivateKeyEntry) entry).getPrivateKey()); // Sign the data, store the result as a Base64 encoded String. s.update(data); byte[] signature = s.sign(); String result = null; result = Base64.encodeToString(signature, Base64.DEFAULT); return result; } /** * Given some data and a signature, uses the key pair stored in the Android * Key Store to verify that the data was signed by this application, using * that key pair. * * @param input * The data to be verified. * @param signatureStr * The signature provided for the data. * @return A boolean value telling you whether the signature is valid or * not. */ public boolean verifyData(String input, String signatureStr) throws KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException, UnrecoverableEntryException, InvalidKeyException, SignatureException { byte[] data = input.getBytes(); byte[] signature; // Make sure the signature string exists. If not, bail out, nothing to // do. if (signatureStr == null) { Log.w(TAG, "Invalid signature."); Log.w(TAG, "Exiting verifyData()..."); return false; } try { // The signature is going to be examined as a byte array, // not as a base64 encoded string. signature = Base64.decode(signatureStr, Base64.DEFAULT); } catch (IllegalArgumentException e) { // signatureStr wasn't null, but might not have been encoded // properly. // It's not a valid Base64 string. return false; } KeyStore ks = KeyStore.getInstance("AndroidKeyStore"); // Weird artifact of Java API. If you don't have an InputStream to load, // you still need // to call "load", or it'll crash. ks.load(null); // Load the key pair from the Android Key Store KeyStore.Entry entry = ks.getEntry(mAlias, null); if (entry == null) { Log.w(TAG, "No key found under alias: " + mAlias); Log.w(TAG, "Exiting verifyData()..."); return false; } if (!(entry instanceof KeyStore.PrivateKeyEntry)) { Log.w(TAG, "Not an instance of a PrivateKeyEntry"); return false; } // This class doesn't actually represent the signature, // just the engine for creating/verifying signatures, using // the specified algorithm. Signature s = Signature .getInstance(SecurityConstants.SIGNATURE_SHA256withRSA); // Verify the data. s.initVerify(((KeyStore.PrivateKeyEntry) entry).getCertificate()); s.update(data); boolean valid = s.verify(signature); return valid; } public void setAlias(String alias) { mAlias = alias; } }