android keystore 公钥,私钥,证书完全解析

来源:互联网 发布:弗洛伊德算法例题 编辑:程序博客网 时间:2024/06/08 15:11

前言

之前不理解公钥私钥,证书的概念,最近总结整理了一下。现在分享出来

注意:从生成签名引出公钥私钥,证书概念

生成key.store

运行--cmd--dos窗口
生成java keystore 文件C:\Users\weichyang>keytool -genkey -alias test -keyalg RSA -keystore key.keystoe输入密钥库口令:再次输入新口令:您的名字与姓氏是什么?  [Unknown]:  yang您的组织单位名称是什么?  [Unknown]:  nuoyuan您的组织名称是什么?  [Unknown]:  nuoyuan您所在的城市或区域名称是什么?  [Unknown]:  bj您所在的省/市/自治区名称是什么?  [Unknown]:  bj该单位的双字母国家/地区代码是什么?  [Unknown]:  010CN=yang, OU=nuoyuan, O=nuoyuan, L=bj, ST=bj, C=010是否正确?  []:  是输入 <test> 的密钥口令        (如果和密钥库口令相同, 按回车):

看上面的有三个关键点:

密钥库密钥口令别名 这几个关键字下面其他步骤会使用到

从keystore中提取公钥

1.首先提取证书,然后查看公钥信息

C:\Users\weichyang>keytool -export -alias test -keystore key.keystore -file zhengshu.cer输入密钥库口令:存储在文件 <zhengshu> 中的证书

-export 导出证书
-alias 证书别名
-keystore 提取证书的keystore名字
-file zhengshu.cer 提取证书名字

找到证书生成路径,双击查看公钥

这样就提取了公钥

这里写图片描述

私钥提取

私钥的提取稍微繁琐了一点。但是有现成提取方法也不必担心

但是我们无法通过KEYTOOL工具来提取私钥的..我们只能通过java的KeyStore类getEntry() 或者getKey()来提取私钥.

贴出来方法

  import java.io.File;import java.io.FileInputStream;import java.io.FileWriter;import java.security.Key;import java.security.KeyPair;import java.security.KeyStore;import java.security.KeyStoreException;import java.security.NoSuchAlgorithmException;import java.security.PrivateKey;import java.security.PublicKey;import java.security.UnrecoverableKeyException;import java.security.cert.Certificate;import sun.misc.BASE64Encoder;public class ExportPrivateKey {    private File keystoreFile;    private String keyStoreType;    private char[] password;    private String alias;    private File exportedFile;    public static KeyPair getPrivateKey(KeyStore keystore, String alias,            char[] password) {        try {            Key key = keystore.getKey(alias, password);            if (key instanceof PrivateKey) {                Certificate cert = keystore.getCertificate(alias);                PublicKey publicKey = cert.getPublicKey();                return new KeyPair(publicKey, (PrivateKey) key);            }        } catch (UnrecoverableKeyException e) {        } catch (NoSuchAlgorithmException e) {        } catch (KeyStoreException e) {        }        return null;    }    public void export() throws Exception {        KeyStore keystore = KeyStore.getInstance(keyStoreType);        BASE64Encoder encoder = new BASE64Encoder();        keystore.load(new FileInputStream(keystoreFile), password);        KeyPair keyPair = getPrivateKey(keystore, alias, password);        PrivateKey privateKey = keyPair.getPrivate();        String encoded = encoder.encode(privateKey.getEncoded());        FileWriter fw = new FileWriter(exportedFile);        fw.write("—–BEGIN PRIVATE KEY—–/n");        System.out.println("—–BEGIN PRIVATE KEY—–/n");        fw.write(encoded);        System.out.println(encoded + "/n");        fw.write("/n");        fw.write("—–END PRIVATE KEY—–");        System.out.println("—–END PRIVATE KEY—–");        fw.close();    }    public static void main(String args[]) throws Exception {        ExportPrivateKey export = new ExportPrivateKey();        export.keystoreFile = new File("c:/Users/weichyang/key.keystore");        export.keyStoreType = "JCEKS";        export.password = "123456".toCharArray();        export.alias = "test";        export.exportedFile = new File("c:/Users/weichyang/11111.txt");        export.export();    }}

执行上面代码会在指定文件中生成一份私钥,同时输出到控制台中

输出私钥:

MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCltQnLjqHJOry7T3iP15XV1VVnORP9MPi/J03j52ygU948L4iSHIJymtS8wtm+XhqVPTTn/a5aqc4D+lqPXiok0NKgWGNFZbnKc2eQb2KXOWg3yaqPIXrvtKQ9vDPeJvNobf9+wILH7L80B4D135/S+lIbHS6V2PxQH5LkWQHx+0R3OBbslzs1FbGL2KEL4UWxUbVeCtfW2wkD2H+u7NeBHq5nSvXfHagjYDHXAGZbUCeZ4ESvKpJf7u5f0wRxpyhDHtv/G+rixnLL0PO50HfAWH8sL1Uu9jwLGuPy/uAYRu8BmcRM2oJc2R+y2azLWwpKNSfDsFY2GZMehvO4LJPRAgMBAAECggEBAI+eXfP4Fg7TgroRgduhrTKc6J1DYijCpgT+6spJTOOUbPva8tI4NXNg8Fr9wjz1ULLiTpV3UAMyQuU9ufmiUoKAHt1sXfXK2gE2jp8netq4nbQkbFgLW4KgHO2IzaeQOMzc8WEJNxBSB9HvYv03KU1xOXJYk4S6gMxs4SJaZo4znaRa4zpb+9ZlVPsuKz2K3ODEwljDzVpVHQagFaeVHpVxVa5YCv5JavlUZ+ijis3MCoK7XvPTpF7Q9Q4DRpDDrBrXILNAs/AazMgGCHVhknIV1x6MATWZr15D0p7aQlso5h8YWmqFrQh/6GfxUfcqOmeMD5to71aavV+y3NYsMTUCgYEA+0OaWQhsm18WUn61itNvLvqr2hs0g4PBB40NwM96Vs0whOxWH+c+3RuRULuHk1LSVC7UWCJx0EFvGCD5fzh6prxpHsTOoG5IOiOIaOfAOmifEOAP9J2fL+8DJ/J1KdhsKkykZ6lLWNnj5M+gD69FGCma8HtbGjHSR9goXHUDiWsCgYEAqNSbZUBw7E7w7eWus5wEfIuikyyin/70WTKfqGOcSBMohtIpsSPu2agfo3X7t9PecLLbRvxLHKvExX9tsE9J16W/kihRO8t16TbDSGCGHZHz+IrM4yrzicg4xoOIigZ1DdGgBlTEoVitqhWE/RMET9+JrLkN3QHrxpepF9LD+rMCgYBcLN6wjsCY9vcPaGBc/1eoWlk0+An5vRnRFVPYScTNlxSXjsPBjGmpX3Wdsk34I8f5DfzkIC60gWyp417j5upHxJKjsPtEK3Dfsy1Vnr8MLlk8LZZs3G4LfZkgzHdi1HxJwDgHtzlm7PgHdot3dYrZZFnsorQ3FdPYe1nDIUIc5QKBgH1On6+87pNV3BiWOt5wVBwkf5wAqwtZbf6uRjXzCNGt9oxqfCtP4j2GPUVTkmrUQ+sdtQawxwcWrktv0vfjQYlfKhrO9cwNrQxVawfTLHfSFmRIkN2iyXNgOlOM2NCpDkQdbEqGrBKdAPiWVEiJzs+BuGuMRi/c9yRE+GoIMxFlAoGBALHWCUJNKCGYSz6Azf1Nscr/PJusGKFCMd1IoHlPrQKMKaxI62ohiyAqyBY0q4EiRg0KyzVvP8T3PHHgAaREUAWhUjTbGUk56PiEWwMtIfrLxuFJA0ZsviWKkQXopHgf8r1fhpfBWJUQkNgztK0rNFvbmRQh2TchFpopgwPxpn0y/n

证书中公钥:

30 82 01 0a 02 82 01 01 00 a5 b5 09 cb 8e a1 c9 3a bc bb 4f 78 8f d7 95 d5 d5 55 67 39 13 fd 30 f8 bf 27 4d e3 e7 6c a0 53 de 3c 2f 88 92 1c 82 72 9a d4 bc c2 d9 be 5e 1a 95 3d 34 e7 fd ae 5a a9 ce 03 fa 5a 8f 5e 2a 24 d0 d2 a0 58 63 45 65 b9 ca 73 67 90 6f 62 97 39 68 37 c9 aa 8f 21 7a ef b4 a4 3dbc 33 de 26 f3 68 6d ff 7e c0 82 c7 ec bf 34 07 80 f5 df 9f d2 fa 52 1b 1d 2e 95 d8 fc 50 1f 92 e4 59 01 f1 fb 44 77 38 16 ec 97 3b 35 15 b1 8b d8 a10b e1 45 b1 51 b5 5e 0a d7 d6 db 09 03 d8 7f ae ec d7 81 1e ae 67 4a f5 df 1d a8 23 60 31 d7 00 66 5b 50 27 99 e0 44 af 2a 92 5f ee ee 5f d3 04 71 a7 28 43 1e db ff 1b ea e2 c6 72 cb d0 f3 b9 d0 77 c0 58 7f 2c 2f 55 2e f6 3c0b 1a e3 f2 fe e0 18 46 ef 01 99 c4 4c da 82 5c d9 1f b2 d9 ac cb 5b 0a 4a35 27 c3 b0 56 36 19 93 1e 86 f3 b8 2c 93 d1 02 03 01 00 01

公钥私钥校验方式:

公钥加密,私钥解密,反之亦然。

验证公钥私钥是否配对

import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileWriter;import java.security.Key;import java.security.KeyPair;import java.security.KeyStore;import java.security.KeyStoreException;import java.security.NoSuchAlgorithmException;import java.security.PrivateKey;import java.security.PublicKey;import java.security.UnrecoverableKeyException;import java.security.cert.Certificate;import java.security.cert.CertificateException;import java.security.cert.CertificateFactory;import javax.crypto.Cipher;import com.sun.org.apache.bcel.internal.generic.NEW;import sun.misc.BASE64Encoder;public class ExportPrivateKey {    private File keystoreFile;    private String keyStoreType;    private char[] password;    private String alias;    private File exportedFile;    public static KeyPair getPrivateKey(KeyStore keystore, String alias,            char[] password) {        try {            Key key = keystore.getKey(alias, password);            if (key instanceof PrivateKey) {                Certificate cert = keystore.getCertificate(alias);                PublicKey publicKey = cert.getPublicKey();                return new KeyPair(publicKey, (PrivateKey) key);            }        } catch (UnrecoverableKeyException e) {        } catch (NoSuchAlgorithmException e) {        } catch (KeyStoreException e) {        }        return null;    }    public PrivateKey export() throws Exception {        KeyStore keystore = KeyStore.getInstance(keyStoreType);        BASE64Encoder encoder = new BASE64Encoder();        keystore.load(new FileInputStream(keystoreFile), password);        KeyPair keyPair = getPrivateKey(keystore, alias, password);        PrivateKey privateKey = keyPair.getPrivate();        String encoded = encoder.encode(privateKey.getEncoded());        FileWriter fw = new FileWriter(exportedFile);        fw.write("—–BEGIN PRIVATE KEY—–/n");        System.out.println("—–BEGIN PRIVATE KEY—–/n");        fw.write(encoded);        System.out.println(encoded + "/n");        fw.write("/n");        fw.write("—–END PRIVATE KEY—–");        System.out.println("—–END PRIVATE KEY—–");        fw.close();        return privateKey;    }    public static void main(String args[]) throws Exception {        ExportPrivateKey export = new ExportPrivateKey();        export.keystoreFile = new File("c:/Users/weichyang/key.keystore");        export.keyStoreType = "JCEKS";        export.password = "123456".toCharArray();        export.alias = "test";        export.exportedFile = new File("c:/Users/weichyang/11111.txt");        PrivateKey  privateKey=export.export();      // 验证加密解密        PublicKey pKey = gePublic();        byte[] plainText = "我用这串字符进行加密".getBytes("UTF-8");        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");        cipher.init(Cipher.ENCRYPT_MODE, pKey);        // 用公钥进行加密,返回一个字节流        byte[] cipherText = cipher.doFinal(plainText);        System.out.println("====================================");        System.out.println(new String(cipherText,"Utf-8"));        System.out.println("====================================");        cipher.init(Cipher.DECRYPT_MODE, privateKey);        // 用私钥进行解密,返回一个字节流        byte[] newPlainText = cipher.doFinal(cipherText);        System.out.println(new String(newPlainText, "UTF-8"));    }private static PublicKey gePublic() {    // 生成一个证书对象并使用从输入流 inStream 中读取的数据对它进行初始化。    try {        CertificateFactory cf = CertificateFactory.getInstance("X.509");        FileInputStream in = new FileInputStream(                "C:/Users/weichyang/zhengshu.cer");        Certificate c = cf.generateCertificate(in);        PublicKey publicKey = c.getPublicKey();        return publicKey;    } catch (CertificateException e) {        // TODO Auto-generated catch block        e.printStackTrace();    } catch (FileNotFoundException e) {        // TODO Auto-generated catch block        e.printStackTrace();    }    return null;}}

输出:

加密串: 我用这串字符进行加密 公钥加密byte[]====================================:K??+H???p)y??倐]<4???w?u_5???(??\??x0??D.?z?0?8???g`??)?]???X????????Mp??<MV??S0H?@?v?еJ??[HcT?h?k}??0+-?36?g?|???pj"???J?'?EL??-?t??N?====================================解密串:我用这串字符进行加密

看到结果,证明提取出来公钥私钥是正确的

总结:

公钥私钥的产生和我们生成keystore中内容有关系,也就是说针对内容使用算法进行加密。生成公钥私钥。
keystore中存在公钥和私钥。当我们用keystore进行apk签名时候,会在MET-INF中的 *.RSA文件中发布公钥信息,和证书。提供给平台进行后期apk唯一性校验。
密钥库口令,密钥口令 是提取的密钥使用的密码。也就是生成keystore时候输入的密码,没有密码当让就无法提取信息了。别名是给生成的keystore文件起的一个别名

引用:
从Java Keystore文件中提取私钥、证书 http://blog.csdn.net/zbuger/article/details/51690900
keystore提取私钥和证书 http://ieroot.com/2014/06/03/1623.html

原创粉丝点击