Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/228.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何将敏感数据(短字符串)安全地存储到密钥库中_Java_Android_Encryption_Android Keystore - Fatal编程技术网

Java 如何将敏感数据(短字符串)安全地存储到密钥库中

Java 如何将敏感数据(短字符串)安全地存储到密钥库中,java,android,encryption,android-keystore,Java,Android,Encryption,Android Keystore,我需要将敏感数据(小字符串)存储到密钥库中。 这里描述的例子正是我需要做的。 问题:我不太懂,我在这方面完全是新手(密码、加密、RSA…) 这就是我正在学习的课程(基于上面提到的这篇文章): 在 所以我需要能够解密存储在密钥库中的私钥,但是这个操作给了我一个错误 我不明白为什么。也许流程中有问题? 请用简单的语言向我解释我做错了什么。@Robert answer在评论中解决了我的问题: 我从中删除了密码\u提供程序 Cipher inputCipher=Cipher.getInstance(R

我需要将敏感数据(小字符串)存储到密钥库中。 这里描述的例子正是我需要做的。 问题:我不太懂,我在这方面完全是新手(密码、加密、RSA…)

这就是我正在学习的课程(基于上面提到的这篇文章):

所以我需要能够解密存储在密钥库中的私钥,但是这个操作给了我一个错误

我不明白为什么。也许流程中有问题?
请用简单的语言向我解释我做错了什么。

@Robert answer在评论中解决了我的问题: 我从中删除了密码\u提供程序


Cipher inputCipher=Cipher.getInstance(RSA_模式,Cipher_提供程序)

@Robert answer在评论中解决了我的问题: 我从中删除了密码\u提供程序


Cipher inputCipher=Cipher.getInstance(RSA_模式,Cipher_提供程序)

也许你可以发布一个我理解的@khelwood,但这是我能做的最小的。。。它可以在Android项目的主要活动中运行。你检查过logcat的错误吗?@Robert sure。resDecrypt函数抛出一个错误:当我尝试:outputCipher.init(Cipher.DECRYPT_模式,privateKeyEntry.getPrivateKey());我捕获到以下错误消息:InvalidKeyException:需要RSA私钥或公钥您使用的密码\u提供程序错误
AndroidOpenSSL
无法处理
AndroidKeyStoreRSAPrivateKey
-这将永远无法工作!为什么不尝试删除提供者规范呢。只需调用
Cipher.getInstance(RSA_模式)
。也许你可以发布一个我理解的@khelwood,但这是我能做的最小的。。。它可以在Android项目的主要活动中运行。你检查过logcat的错误吗?@Robert sure。resDecrypt函数抛出一个错误:当我尝试:outputCipher.init(Cipher.DECRYPT_模式,privateKeyEntry.getPrivateKey());我捕获到以下错误消息:InvalidKeyException:需要RSA私钥或公钥您使用的密码\u提供程序错误
AndroidOpenSSL
无法处理
AndroidKeyStoreRSAPrivateKey
-这将永远无法工作!为什么不尝试删除提供者规范呢。只需调用Cipher.getInstance(RSA_模式)。
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.security.KeyPairGeneratorSpec;
import android.security.keystore.KeyProperties;
import android.support.v7.app.AppCompatActivity;
import android.util.Base64;
import android.util.Log;
import android.widget.Toast;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.math.BigInteger;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.KeyStore;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Calendar;

import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.spec.SecretKeySpec;
import javax.security.auth.x500.X500Principal;


public class SecondActivity extends AppCompatActivity {

    static final String TAG = "SimpleKeystoreApp";
    static final String CIPHER_PROVIDER = "AndroidOpenSSL";
    private static final String RSA_MODE = "RSA/ECB/PKCS1Padding";
    private static final String AES_MODE = "AES/ECB/PKCS7Padding";
    private static final String KEY_ALIAS = "this is my alias";
    private static final String SHARED_PREFENCE_NAME = "my shared_prefs";
    private static final String ENCRYPTEDKEY_KEY = "encrypted_key";
    private static final String TO_BE_ENCRYPTED_KEY = "this is my test";
    private static final String ANDROID_KEYSTORE = "AndroidKeyStore";

    KeyStore keyStore;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        try {
            keyStore = KeyStore.getInstance(ANDROID_KEYSTORE);
            keyStore.load(null);
        } catch (Exception e) {
            Log.d(TAG, e.getMessage());
        }

        createNewKeys();

        try {
            generateAndStoreAESKey();
        } catch (Exception e) {
            Log.d(TAG, "couldn't generateAndStoreAESKey:" + e.getMessage());
        }
        String encrypted = null;
        try {
            encrypted = encrypt(getApplicationContext(), TO_BE_ENCRYPTED_KEY.getBytes());
            Log.d(TAG, "encrypted:" + encrypted);
        } catch (Exception e) {
            Log.d(TAG, "couldn't encrypt:" + e.getMessage());
        }

        try {
            decrypt(getApplicationContext(), encrypted.getBytes());
            Log.d(TAG, "decrypted:" + encrypted);
        } catch (Exception e) {
            Log.d(TAG, "couldn't decrypt:" + e.getMessage());
        }
        setContentView(R.layout.activity_main);
    }

    public void createNewKeys() {
        Log.d(TAG, "___ createNewKeys");
        try {
            // Create new key if needed
            // Generate the RSA key pairs
            keyStore = KeyStore.getInstance(ANDROID_KEYSTORE);
            keyStore.load(null);
            // Generate the RSA key pairs
            if (!keyStore.containsAlias(KEY_ALIAS)) {
                // Generate a key pair for encryption
                Calendar start = Calendar.getInstance();
                Calendar end = Calendar.getInstance();
                end.add(Calendar.YEAR, 30);
                KeyPairGeneratorSpec spec = new KeyPairGeneratorSpec.Builder(this)
                        .setAlias(KEY_ALIAS)
                        .setSubject(new X500Principal("CN=" + KEY_ALIAS))
                        .setSerialNumber(BigInteger.TEN)
                        .setStartDate(start.getTime())
                        .setEndDate(end.getTime())
                        .build();
                KeyPairGenerator kpg = KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_RSA, ANDROID_KEYSTORE);
                kpg.initialize(spec);
                kpg.generateKeyPair();

                KeyPair keyPair = kpg.generateKeyPair();
                Log.d(TAG, "Public Key is: " + keyPair.getPublic().toString());
            }
        } catch (Exception e) {
            Toast.makeText(this, "Exception " + e.getMessage() + " occured", Toast.LENGTH_LONG).show();
            Log.e(TAG, Log.getStackTraceString(e));
        }
    }

    private void generateAndStoreAESKey() throws Exception{
        Log.d(TAG, "___ generateAndStoreAESKey");

        SharedPreferences pref = getApplicationContext().getSharedPreferences(SHARED_PREFENCE_NAME, Context.MODE_PRIVATE);
        String enryptedKeyB64 = pref.getString(ENCRYPTEDKEY_KEY, null);
        if (enryptedKeyB64 == null) {
            byte[] key = new byte[16];
            SecureRandom secureRandom = new SecureRandom();
            secureRandom.nextBytes(key);
            byte[] encryptedKey = rsaEncrypt(key);
            enryptedKeyB64 = Base64.encodeToString(encryptedKey, Base64.DEFAULT);
            SharedPreferences.Editor edit = pref.edit();
            edit.putString(ENCRYPTEDKEY_KEY, enryptedKeyB64);
            edit.commit();
        }
    }
    private SecretKeySpec getSecretKey(Context context) throws Exception{
        SharedPreferences pref = context.getSharedPreferences(SHARED_PREFENCE_NAME, Context.MODE_PRIVATE);
        String enryptedKeyB64 = pref.getString(ENCRYPTEDKEY_KEY, null);
        // need to check null, omitted here
        byte[] encryptedKey = Base64.decode(enryptedKeyB64, Base64.DEFAULT);
        byte[] key = rsaDecrypt(encryptedKey);
        return new SecretKeySpec(key, "AES");
    }

    public String encrypt(Context context, byte[] input) throws Exception{
        Cipher c = Cipher.getInstance(AES_MODE, "BC");
        c.init(Cipher.ENCRYPT_MODE, getSecretKey(context));
        byte[] encodedBytes = c.doFinal(input);
        String encryptedBase64Encoded =  Base64.encodeToString(encodedBytes, Base64.DEFAULT);
        return encryptedBase64Encoded;
    }


    public byte[] decrypt(Context context, byte[] encrypted) throws Exception{
        Cipher c = Cipher.getInstance(AES_MODE, "BC");
        c.init(Cipher.DECRYPT_MODE, getSecretKey(context));
        byte[] decodedBytes = c.doFinal(encrypted);
        return decodedBytes;
    }


    private byte[] rsaEncrypt(byte[] secret) throws Exception{
        KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry) keyStore.getEntry(KEY_ALIAS, null);
        // Encrypt the text
        Cipher inputCipher = Cipher.getInstance(RSA_MODE, CIPHER_PROVIDER);
        inputCipher.init(Cipher.ENCRYPT_MODE, privateKeyEntry.getCertificate().getPublicKey());

        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        CipherOutputStream cipherOutputStream = new CipherOutputStream(outputStream, inputCipher);
        cipherOutputStream.write(secret);
        cipherOutputStream.close();

        byte[] vals = outputStream.toByteArray();
        return vals;
    }

    private  byte[]  rsaDecrypt(byte[] encrypted) throws Exception {
        KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry) keyStore.getEntry(KEY_ALIAS, null);
        Cipher output = Cipher.getInstance(RSA_MODE, CIPHER_PROVIDER);
        output.init(Cipher.DECRYPT_MODE, privateKeyEntry.getPrivateKey());
        CipherInputStream cipherInputStream = new CipherInputStream(
                new ByteArrayInputStream(encrypted), output);
        ArrayList<Byte> values = new ArrayList<>();
        int nextByte;
        while ((nextByte = cipherInputStream.read()) != -1) {
            values.add((byte)nextByte);
        }

        byte[] bytes = new byte[values.size()];
        for(int i = 0; i < bytes.length; i++) {
            bytes[i] = values.get(i).byteValue();
        }
        return bytes;
    }
}
outputCipher.init(Cipher.DECRYPT_MODE, privateKeyEntry.getPrivateKey());
private  byte[]  rsaDecrypt(byte[] encrypted)