java加密之我见

        在java项目中我们经常需要用到加密,比如说密码的加密,关键配置文件的加密,许可证文件的加密,这里我就分享一下我在项目中用到过的加密手段,如果理解错误的地方,还希望能够得到大虾的指点。
        在说加密之前,我还要先讲一下BASE64散列算法,很多人认为它也算是一种加密手段,但在我看来BASE64只是一个散列排序,属于一种编码格式,而不能称得上加密手段,只是我们平时使用过程中可以把它拿来用作代码混淆的一种手段。
        接下来就是加密,首先加密分单向加密,以及非单向加密,至少我是这么理解的,所谓单向加密就是java中没有提供主流的反破解工具的加密方式,相对的就是非单向加密。
        首先单向加密,最大家熟知的可能就是MD5信息摘要算法了,其次就是SHA安全散列算法,还有就是HMAC散列消息鉴别码(自己没有用过)。
        首先是MD5,这里文件的MD5加密就不说了,因为本文主要讲解字符串加密。我们的MD5信息摘要算法平时还是挺常用的,因为是jdk自带的一种加密手段,我们可以直接像以下代码这样使用就可以将我们的字符串给加密了。

String bb=DigestUtils.md5Hex(aa);

        但是MD5也是有一些它所拥有特点的,就是网络上有提供一些MD5的解密的工具,但是只有比较简单的可以得到免费的解密,比较复杂的都需要支付一些资费,在我的了解里现实中复杂的MD5解码正常个人电脑有时候也不是一两天可以搞定的。所以MD5一般只是用来加密,很少用来解密。
        接下来就是SHA安全散列算法,它和MD5有些类似,不可逆,而且它的破解难度比MD5要高的很多,所以从名字既可以看出SHA的安全性相对还是比较高的。
        下面就来介绍SHA的使用,首先它目前有五种使用规范(我是这么来理解的哦)吧,SHA-1,SHA-224,SHA-256,SHA-384,和SHA-512,我这里用的是384的。

/**
     * SHA散列编码<br/>
     * 通过该方法就可以讲文件进行SHA散列排序,这里没有提供SHA散列解码的方法,所有我们提供的包SHA散列是不可逆的。
     * 
     * @param plaintext
     * @return
     * @throws Exception
     */
    public static String encryptSHA(byte[] plaintext) throws Exception {
        MessageDigest md = MessageDigest.getInstance(SHA-384);
        md.update(plaintext);
        return bytes2Hex(md.digest());
    }

    /**
     * 
     * @param bts
     * @return
     */
    static String bytes2Hex(byte[] bts) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < bts.length; i++) {
            sb.append(toHex(bts[i]));
        }
        return sb.toString();
    }

    /**
     * 
     * @param buf
     * @return
     */
    static String toHex(byte buf) {
        int n = buf >= 0 ? buf : 256 + buf;
        String str = Integer.toHexString(n);
        return str.toUpperCase();
    }

        当然SHA最主要的特性就是安全性,不可逆性,是一种比较常用的加密手段之一。
        之后的HMAC我保留意见,如果之后有使用再过来补吧。
        接下啦再讲一下非单向加密,出名的不出名的有好多,DES(数据加密算法)、PBE(基于密码验证) 、RSA、DH(密钥一致协议)、DSA(数字签名)、ECC(椭圆曲线密码编码学),而我自己也只用过RSA,废话不都说,先讲一下我使用多的RSA吧。

        使用RSA吧,感觉还是挺方便的,没有那么繁琐,唯一感觉不是太好的就是他的解码不是很快,但是正常用还是足够了。下面是它的代码部分:

    private static final String KEY_PATH = "C:\\";

    public static void main(String[] args) throws Exception {
        File savePath = new File(KEY_PATH);
        saveKeyPair(generateKeyPair(), savePath);
        System.out.println("----------- Key generate success -----------");
    }

    public static KeyPair generateKeyPair() throws NoSuchAlgorithmException {
        KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
        final int KEY_SIZE = 1024;
        keyPairGen.initialize(KEY_SIZE, new SecureRandom());
        KeyPair keyPair = keyPairGen.genKeyPair();
        return keyPair;
    }


    public static void saveKeyPair(KeyPair keyPair, File savePath) throws IOException {

        // Save Pirvate Key
        saveObject(keyPair.getPrivate(), new File(savePath, "private.key"));

        // Save Public Key
        saveObject(keyPair.getPublic(), new File(savePath, "public.key"));
    }


    private static void saveObject(Object obj, File fileFullName) throws IOException {

        FileOutputStream fout = null;
        ObjectOutputStream objOut = null;
        try {
            fout = new FileOutputStream(fileFullName);
            objOut = new ObjectOutputStream(fout);
            objOut.writeObject(obj);
            objOut.flush();
            fout.flush();
        }
        finally {
            if (null != objOut) {
                objOut.close();
            }
            if (null != fout) {
                fout.close();
            }
        }
    }


    public static byte[] encodeRSA(File publicKeyFile, byte[] plaintext) throws Exception {
        FileInputStream publicKeyFin = null;
        ObjectInputStream pubObjIn = null;
        try {
            publicKeyFin = new FileInputStream(publicKeyFile);
            pubObjIn = new ObjectInputStream(publicKeyFin);
            // 获取公钥
            RSAPublicKey pbk = (RSAPublicKey) pubObjIn.readObject();
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.ENCRYPT_MODE, pbk);
            return cipher.doFinal(plaintext);
        }
        finally {
            if (null != pubObjIn) {
                pubObjIn.close();
            }
            if (null != publicKeyFin) {
                publicKeyFin.close();
            }
        }
    }

    public static byte[] decryptRSA(File privateKeyFile, byte[] ciphertext)
            throws Exception {
        // 获取私钥
        FileInputStream privateKeyFin = null;
        ObjectInputStream priObjIn = null;
        try {
            privateKeyFin = new FileInputStream(privateKeyFile);
            priObjIn = new ObjectInputStream(privateKeyFin);
            RSAPrivateKey prk = (RSAPrivateKey) priObjIn.readObject();
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.DECRYPT_MODE, prk);
            return cipher.doFinal(ciphertext);
        }
        finally {
            if (null != priObjIn) {
                priObjIn.close();
            }
            if (null != privateKeyFin) {
                privateKeyFin.close();
            }
        }
    }

        下面来稍微解释一下RSA的用法吧,使用RSA首先我们需要一对公钥私钥,通过上面的main方法产生一对公钥私钥,然后就可以通过公钥私钥来解密加密了,我这上面的代码主要实现的是公钥加密,私钥解密,代码看的有问题的也可以留言问。

        其他非单向加密也没有怎么用,暂时就讲到这里吧,以后有新的再来更新。

       

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值