KeyStore秘钥库

KeyStore秘钥库,第1张

keytool

在打包Android APK的时候进行签名需要选择一个keystore,查看秘钥库:

C:\Users\47355\.android>keytool -list -v -keystore debug.keystore
输入密钥库口令:
密钥库类型: PKCS12
密钥库提供方: SUN
您的密钥库包含 1 个条目
别名: androiddebugkey
条目类型: PrivateKeyEntry
证书链长度: 1
证书[1]:
所有者: C=US, O=Android, CN=Android Debug
发布者: C=US, O=Android, CN=Android Debug
序列号: 1
生效时间: Mon Mar 07 12:44:02 CST 2022, 失效时间: Wed Feb 28 12:44:02 CST 2052
证书指纹:
SHA1: 5B:AE:41:23:D7:B4:40:DA:70:F2:D7:C6:25:A0:F1:45:6A:23:A8:9E
SHA256: 77:CE:12:A1:9B:FA:5E:40:DD:C1:B7:1B:C4:58:E1:A0:A7:50:D7:DF:2C:87:A5:82:DD:3F:A7:11:77:BB:52:BE
签名算法名称: SHA1withRSA ()
主体公共密钥算法: 2048 位 RSA 密钥
版本: 1
Warning:
<androiddebugkey> 使用的 SHA1withRSA 签名算法被视为存在安全风险。此算法将在未来的更新中被禁用。

使用Android studio生成秘钥库:

使用Java的keytool生成秘钥库:

keytool -genkey -alias ali1 -keyalg RSA -keysize 1024 -keystore C:\Users\47355\Desktop\kst\bbb.keystore
使用Java代码生成秘钥库
public static void main(String[] args) throws GeneralSecurityException {
        try {

            /**
             * PKCS12,这是一个标准的密钥库类型,可以在Java和其他语言中使用。
             * 您可以在sun.security.pkcs12.PKCS12KeyStore找到这个密钥库的实现。
             * 它通常有p12或pfx的扩展。您可以在此类型上存储私钥、密钥和证书。
             * 与JKS不同,PKCS12密钥库上的私钥可以用Java提取。
             * 这种类型是可移植的,可以与其他语言编写的其他库一起 *** 作,如C、C++或C语言
             */
//            KeyStore ks = KeyStore.getInstance("JKS");
//            KeyStore ks = KeyStore.getInstance(ANDROID_KEY_STORE);
//            KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
//            KeyStore ks = KeyStore.getInstance(PKCS12_KEYSTORE_TYPE, BouncyCastleProvider.PROVIDER_NAME);
            KeyStore ks = KeyStore.getInstance("pkcs12");
            ks.load(null, null);

            /**
             * 签名算法名称: SHA1withRSA、SHA256withRSA
             */
            CertAndKeyGen certAndKeyGen = new CertAndKeyGen("RSA", "SHA1WithRSA", null);
            /**
             * keySize除了1024还有2048
             */
            certAndKeyGen.generate(keysize);
            PrivateKey privateKey = certAndKeyGen.getPrivateKey();
            PublicKey publicKey = certAndKeyGen.getPublicKey();
            
            X509Certificate[] chain = new X509Certificate[1];
            X500Name x500Name = new X500Name(commonName, organizationalUnit, organization, city, state, country);
            chain[0] = certAndKeyGen.getSelfCertificate(x500Name, new Date(), (long)validity*24*60*60);

            // store away the key store
            FileOutputStream fos = new FileOutputStream(filePath);
            /**
             * 此处只能用privateKey
             */
//            ks.setKeyEntry(alias, publicKey, keyPassword, chain);
            ks.setKeyEntry(alias, privateKey, keyPassword, chain);
            ks.store(fos, keyPassword);
            fos.close();
            System.out.println("create Success");
        } catch (KeyStoreException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (CertificateException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
Java代码验证签名
static Cipher cipher;
    static {
        // 使用默认RSA
        try {
            cipher = Cipher.getInstance("RSA");
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws Exception {
        FileInputStream is = new FileInputStream(new File("C:\Users\47355\Desktop\kst\aaa.jks"));
        KeyStore keyStore = KeyStore.getInstance("JKS");
        keyStore.load(is, "s7865787".toCharArray());

        /**
         * 别名
         */
        Enumeration aliasEnum = keyStore.aliases();
        String keyAlias = "" ;
        while (aliasEnum.hasMoreElements()) {
            keyAlias = (String) aliasEnum.nextElement();
            System.out.println("别名"+keyAlias);
        }

        /**
         * 证书指纹
         */
        Certificate certificate = keyStore.getCertificate(keyAlias);
        X509Certificate x509Certificate = (X509Certificate) certificate;
        digest(x509Certificate.getEncoded(),"SHA-1");

        /**
         *加载公钥
         */
        PublicKey publicKey = certificate.getPublicKey();
        /**
         * 加载私钥,这里填私钥密码
         */
        KeyStore.Entry keyStoreEntry = keyStore.getEntry(keyAlias,
                new KeyStore.PasswordProtection("s7865787".toCharArray()));
        KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry) keyStoreEntry;
        PrivateKey privateKey = privateKeyEntry.getPrivateKey();

        /**
         * 加载私钥另一写法
         */
        //PrivateKey privateKey = (PrivateKey) keyStore.getKey(keyAlias, "123456".toCharArray());

        /**
         * base64输出私钥
         * Base64是一种用64个字符来表示任意二进制数据的方法。它是一种编码方式,而非加密方式。
         * 它通过将二进制数据转变为64个“可打印字符”,完成了数据在HTTP协议上的传输
         */
        String strKey = Base64.getEncoder().encodeToString(privateKey.getEncoded());
        System.out.println("Base64输出私钥:"+strKey);

        /**
         * 签名 + 验签 + 编码
         */
//        String signBase64Encoded = Base64.getEncoder().encodeToString(sign("测试msg".getBytes(),privateKey,"SHA1withRSA",null));
//        boolean verfi = verify("测试msg".getBytes(),Base64.getDecoder().decode(signBase64Encoded), publicKey,"SHA1withRSA",null);
//        System.out.println(verfi);

        /**
         * 签名(私钥加密) + 验签
         */
        String message = "我是消息";
        byte[] signature = sign(message.getBytes(StandardCharsets.UTF_8), privateKey, "SHA1withRSA", null);
        boolean verify = verify(message.getBytes(StandardCharsets.UTF_8), signature,publicKey, "SHA1withRSA", null);
        System.out.println("验签结果:"+verify);

        /**
         * 摘要
         */
//        byte[] privateEncrypted = privateEncrypt(message.getBytes(StandardCharsets.UTF_8), privateKey);
        byte[] digest = digest(message.getBytes(StandardCharsets.UTF_8), "SHA-1");
        /**
         * 私钥加密摘要
         * 使用Cipher进行私钥加密 r1
         * 使用RSACore进行私钥加密 r2
         * signature.sign()     r3
         * 结论:r1、r2、r3三者不相等
         */
        byte[] privateEncrypted = privateEncryptWithCipherRSA(digest, privateKey);
        byte[] privateEncrypted2 = RSACore.rsa(digest, (RSAPrivateKey)privateKey, true);

        /**
         * 公钥解密
         */
        // publicDecrypted 等于 digest,公钥解密成功
        byte[] publicDecrypted = publicDecryptWithCipherRSA((RSAPublicKey) publicKey, privateEncrypted);

        /**
         * 公钥加密
         */
        byte[] publicEncrypted = publicEncrypt(digest, publicKey);

        /**
         * 私钥解密
         */
        final byte[] privateDecrypted = privateDecrypt(privateKey, publicEncrypted);
        System.out.println("end");

    }

    /**
     * 公钥解密
     */
    public static byte[] publicDecryptWithCipherRSA(RSAPublicKey publicKey, byte[] cipherData)
            throws Exception {
        Cipher cipher;
        try {
            // 使用默认RSA
            cipher = Cipher.getInstance("RSA");
            // cipher= Cipher.getInstance("RSA", new BouncyCastleProvider());
            cipher.init(Cipher.DECRYPT_MODE, publicKey);
            byte[] output = cipher.doFinal(cipherData);
            return output;
        } catch (NoSuchAlgorithmException e) {
            throw new Exception("无此解密算法");
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
            return null;
        } catch (InvalidKeyException e) {
            throw new Exception("解密公钥非法,请检查");
        } catch (IllegalBlockSizeException e) {
            throw new Exception("密文长度非法");
        } catch (BadPaddingException e) {
            throw new Exception("密文数据已损坏");
        }
    }

    /**
     * 私钥解密
     */
    public static byte[] privateDecrypt(PrivateKey privateKey, byte[] cipherData)
            throws Exception {
        byte[] output = null;
        try {
            // cipher= Cipher.getInstance("RSA", new BouncyCastleProvider());
            cipher.init(Cipher.DECRYPT_MODE, privateKey);
            output = cipher.doFinal(cipherData);
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            throw new Exception("密文长度非法");
        } catch (BadPaddingException e) {
            throw new Exception("密文数据已损坏");
        }
        return output;
    }

    /**
     * 私钥加密
     */
    public static byte[] privateEncryptWithCipherRSA(byte[] messageBytes,PrivateKey privateKey) {
        Cipher cipher;
        try {
            // 使用默认RSA
            cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.ENCRYPT_MODE, privateKey);
            byte[] output = cipher.doFinal(messageBytes);
            return output;
        } catch (NoSuchAlgorithmException e) {
            // 无此加密算法
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            // 加密私钥非法,请检查
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            // 明文长度非法
            e.printStackTrace();
        } catch (BadPaddingException e) {
            // 明文数据已损坏
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 公钥加密
     */
    public static byte[] publicEncrypt(byte[] messageBytes,PublicKey publicKey) {
        try {
            cipher.init(Cipher.ENCRYPT_MODE, publicKey);
            byte[] output = cipher.doFinal(messageBytes);
            return output;
        } catch (IllegalBlockSizeException | InvalidKeyException e) {
            // 明文长度非法
            e.printStackTrace();
        } catch (BadPaddingException e) {
            // 明文数据已损坏
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 计算字节数组指纹
     */
    public static byte[] digest(byte[] der,String algorithm) throws NoSuchAlgorithmException, CertificateEncodingException {
        /**
         * 证书指纹
         */
//        MessageDigest md = MessageDigest.getInstance("SHA-1");
//        MessageDigest md = MessageDigest.getInstance("md5");
//        MessageDigest md = MessageDigest.getInstance("sha-256");
        MessageDigest md = MessageDigest.getInstance(algorithm);
        md.update(der);
        byte[] digest = md.digest();
        String digestHex = DatatypeConverter.printHexBinary(digest);
        final String s = digestHex.toLowerCase();
        return digest;
    }

    /**
     * 签名
     */
    public static byte[] sign(byte[] message, PrivateKey privateKey, String algorithm, String provider) throws Exception {
        Signature signature;
        if (null == provider || provider.length() == 0) {
            signature = Signature.getInstance(algorithm);
        } else {
            signature = Signature.getInstance(algorithm, provider);
        }
        signature.initSign(privateKey);
        signature.update(message);
        return signature.sign();
    }

    /**
     * 验签
     */
    public static boolean verify(byte[] message, byte[] signMessage, PublicKey publicKey, String algorithm,
                                 String provider) throws Exception {
        Signature signature;
        if (null == provider || provider.length() == 0) {
            signature = Signature.getInstance(algorithm);
        } else {
            signature = Signature.getInstance(algorithm, provider);
        }

        signature.initVerify(publicKey);
        signature.update(message);
        return signature.verify(signMessage);
    }

欢迎分享,转载请注明来源:内存溢出

原文地址:https://www.54852.com/web/992831.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-21
下一篇2022-05-21

发表评论

登录后才能评论

评论列表(0条)

    保存