我已经编写了一个API,以便我的不同应用程序可以使用它。它只是检查应用程序是否在服务器上注册。如果不是那么它会生成公钥/私钥对,并获得通过将CSR发送到我的服务器来签署证书。下一次它使用签名证书和私钥。最初,我有原始的默认密钥库文件(B/C所有我的通信是通过SSL,即最初使用默认密钥库,并在用户生成密钥库注册后)如何安全地保存我的密钥库
我的API工作正常。我所遇到的问题与我缺乏知识或错误的做法有些相关,因此我需要帮助。
我使用下面的类来保存/恢复我的密钥对
public class KeyIOHandler {
public static void writePublicKeyToPreferences(KeyPair key, Context context) {
StringWriter publicStringWriter = new StringWriter();
try {
PemWriter pemWriter = new PemWriter(publicStringWriter);
pemWriter.writeObject(new PemObject("myapp.PUBLIC KEY", key.getPublic().getEncoded()));
pemWriter.flush();
pemWriter.close();
SharedPreferences preferences = context.getSharedPreferences("SHARED_PREFERENCES",0);
preferences.edit().putString("RSA_PUBLIC_KEY", publicStringWriter.toString()).commit();
Log.e("Public Key", publicStringWriter.toString());
} catch (IOException e) {
Log.e("RSA", e.getMessage());
e.printStackTrace();
}
}
public static void writePrivateKeyToPreferences(KeyPair keyPair, Context context) {
StringWriter privateStringWriter = new StringWriter();
try {
PemWriter pemWriter = new PemWriter(privateStringWriter);
pemWriter.writeObject(new PemObject("myapp.PRIVATE KEY", keyPair.getPrivate().getEncoded()));
pemWriter.flush();
pemWriter.close();
SharedPreferences preferences = context.getSharedPreferences("SHARED_PREFERENCES",0);
preferences.edit().putString("RSA_PRIVATE_KEY", privateStringWriter.toString()).commit();
Log.e("Private Key",privateStringWriter.toString());
} catch (IOException e) {
Log.e("RSA", e.getMessage());
e.printStackTrace();
}
}
public static PublicKey getRSAPublicKeyFromString(String publicKeyPEM) throws Exception {
publicKeyPEM = stripPublicKeyHeaders(publicKeyPEM);
KeyFactory keyFactory = KeyFactory.getInstance("RSA", "SC");
byte[] publicKeyBytes = Base64.decode(publicKeyPEM.getBytes("UTF-8"));
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(publicKeyBytes);
return keyFactory.generatePublic(x509KeySpec);
}
public static PrivateKey getRSAPrivateKeyFromString(String privateKeyPEM) throws Exception {
privateKeyPEM = stripPrivateKeyHeaders(privateKeyPEM);
KeyFactory fact = KeyFactory.getInstance("RSA", "SC");
byte[] clear = Base64.decode(privateKeyPEM);
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(clear);
PrivateKey priv = fact.generatePrivate(keySpec);
Arrays.fill(clear, (byte) 0);
return priv;
}
public static String stripPublicKeyHeaders(String key) {
//strip the headers from the key string
StringBuilder strippedKey = new StringBuilder();
String lines[] = key.split("\n");
for (String line : lines) {
if (!line.contains("BEGIN PUBLIC KEY") && !line.contains("END PUBLIC KEY") && !isNullOrEmpty(line.trim())) {
strippedKey.append(line.trim());
}
}
return strippedKey.toString().trim();
}
public static String stripPrivateKeyHeaders(String key) {
StringBuilder strippedKey = new StringBuilder();
String lines[] = key.split("\n");
for (String line : lines) {
if (!line.contains("BEGIN PRIVATE KEY") && !line.contains("END PRIVATE KEY") && !isNullOrEmpty(line.trim())) {
strippedKey.append(line.trim());
}
}
return strippedKey.toString().trim();
}
public static boolean isNullOrEmpty(String str) {
return str == null || str.isEmpty();
}
}
,并通过以下方法,我生成我的密钥库,但我搞不清如何以及在哪里可以安全地存储此密钥库,使我可以在应用程序的其余部分使用它(除非密钥被盗)。正如在共享偏好我不能存储任何对象,所以在哪里保存这个keystore.Right现在我有我的类中的静态密钥库对象(这是我知道最糟糕,但只是为了使它工作,我已经使它静态)
private boolean addToStore(){
try {
Security.insertProviderAt(new org.spongycastle.jce.provider.BouncyCastleProvider(), 1);
clientPkcs12 = KeyStore.getInstance("PKCS12");
clientPkcs12.load(null, null);
clientPkcs12.setKeyEntry("clientCert", keyPair.getPrivate(), "123456".toCharArray(), chain);
}
catch(Exception ex){
Log.e("",ex.getCause().getMessage());
}
return false;
}
我已经经历了几个帖子,其中这是显而易见的一个nelenkov.blogspot,但没有得到我如何实现我的目标,或者我在保存密钥库时出错?我的意思是每次都必须创建密钥存储区?
thnx回复,我已经提到可能是我错了,所以如你所说我有两件事要问,1#我需要将我的密钥保存在SP中,因为我正在做或只有密钥库足够? 2#在哪里保存这个文件,以便其他人不能访问它? – SSH
@SSH我编辑了我的答案,您的评论回复 – Than
thnx再次,测试与此,将接受您的答案,一旦我将获得成功 – SSH