关闭

Java中RSA非对称密钥加解密使用示例

发表于:2012-9-07 09:59

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:huozhicheng    来源:51Testing软件测试网采编

  一、简介:

  RSA加密算法是最常用的非对称加密算法,CFCA在证书服务中离不了它。RSA是第一个比较完善的公开密钥算法,它既能用于加密,也能用于数字签名。这个算法经受住了多年深入的密码分析,虽然密码分析者既不能证明也不能否定RSA的安全性,但这恰恰说明该算法有一定的可信性,目前它已经成为最流行的公开密钥算法。

  二、RSA的公钥、私钥的组成,以及加密、解密的公式可见于下表

  三、使用方式:

  ① 假设A、B机器进行通信,已A机器为主;

  ② A首先需要用自己的私钥为发送请求数据签名,并将公钥一同发送给B;

  ③ B收到数据后,需要用A发送的公钥进行验证,已确保收到的数据是未经篡改的;

  ④ B验签通过后,处理逻辑,并把处理结果返回,返回数据需要用A发送的公钥进行加密(公钥加密后,只能用配对的私钥解密);

  ⑤ A收到B返回的数据,使用私钥解密,至此,一次数据交互完成。

  四、代码示例:

  1、第一步获取私钥,为签名做准备。

/**
     * 读取私钥  返回PrivateKey
     * @param path  包含私钥的证书路径
     * @param password  私钥证书密码
     * @return 返回私钥PrivateKey
     * @throws KeyStoreException
     * @throws NoSuchAlgorithmException
     * @throws CertificateException
     * @throws IOException
     * @throws UnrecoverableKeyException
     */
    private static PrivateKey getPrivateKey(String path,String password)
            throws KeyStoreException, NoSuchAlgorithmException, CertificateException,
            IOException, UnrecoverableKeyException {
        KeyStore ks = KeyStore.getInstance("PKCS12");
        FileInputStream fis = new FileInputStream(path);
        char[] nPassword = null;
        if ((password == null) || password.trim().equals("")) {
            nPassword = null;
        } else {
            nPassword = password.toCharArray();
        }
        ks.load(fis, nPassword);
        fis.close();
        Enumeration<String> en = ks.aliases();
        String keyAlias = null;
        if (en.hasMoreElements()) {
            keyAlias = (String) en.nextElement();
        }
 
        return (PrivateKey) ks.getKey(keyAlias, nPassword);
    }

  2、签名示例:通过第一步得到的私钥,进行签名操作,具体请看以下代码:

/**
     * 私钥签名: 签名方法如下:BASE64(RSA(MD5(src),privatekey)),其中src为需要签名的字符串,
privatekey是商户的CFCA证书私钥。
     * @param plainText 待签名字符串
     * @param path 签名私钥路径
     * @param password  签名私钥密码
     * @return 返回签名后的字符串
     * @throws Exception
     */
    public static String sign(String plainText,String path,String password)
            throws Exception  {
        /*
         * MD5加密
         */
        MessageDigest md5 = MessageDigest.getInstance("MD5");
        md5.update(plainText.getBytes("utf-8"));
        byte[] digestBytes = md5.digest();
        /*
         * 用私钥进行签名 RSA
         * Cipher负责完成加密或解密工作,基于RSA
         */
        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        //ENCRYPT_MODE表示为加密模式
        cipher.init(Cipher.ENCRYPT_MODE, getPrivateKey(path, password));
        //加密
        byte[] rsaBytes = cipher.doFinal(digestBytes);
        //Base64编码
        return Base64.byteArrayToBase64(rsaBytes);

21/212>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号