java 加密技术(一)

java 加密技术(一)

OutLine

1. java安全介绍
2. Base64加密
3. 消息摘要–MD
4. SHA消息摘要

1 java安全介绍

1.1 java安全组成
  • JCA (java Cryptography Architecture) java加密体系结构
  • JCE (java Cryptography Extension) java加密扩展包
  • JSSE(java Secure Socket Extension) java安全套接字的扩展包
  • JAAS (java Authentication and Authentication Service) java鉴别与安全服务
1.2 相关java包
  • java.security :信息摘要相关的包
  • javax.crypto: 安全消息摘要,消息验证码
  • java.net.ssl : 安全套接字
1.3 扩展jar包
  • Bouncy Castle
  • Commons Codec (Apache提供; Base64,二进制,十六进制, 字符集编码; Url编码/解码)

2 Base64加密

2.1 Base64介绍

严格意义上,Base64算法不算是加解密算法,主要是进行编码工作,它可以将特殊字符编码成非特殊字符.但是存储空间会比加密之前的文件存储空间多出1/3.

2.2 代码实现

下面我们简称java提供的jar包实现叫做jdk实现,Bouncy Castle的实现叫做BC实现, Commons Codec实现叫做CC实现.

package screte;

import java.util.Base64;
import java.util.Base64.Decoder;
import java.util.Base64.Encoder;

public class Base64Test {
public static String src = "i am gc base64";

public static void main(String[] args) {
    //jdk对Base64编码的支持
    System.out.println("=====jdkBase64编码测试=====");
    jdkBase64();
    System.out.println("==========================");
    System.out.println("=====CommonsCodec的Base64实现=====");
    commonsCodecBase64();
    System.out.println("==========================");
    System.out.println("=====BouncyCastle的Base64实现=====");
    bouncyCastleBase64();
    System.out.println("==========================");

}
public static void jdkBase64(){
    //加密
    //获取Encoder对象
    Encoder encoder = Base64.getEncoder(); 
    //用Encoder对象对字符串进行加密
    byte[] result = encoder.encode(src.getBytes());
    System.out.println("Base64编码之后::"+new String(result));

    //解密
    //获取Decoder对象
    Decoder decoder = Base64.getDecoder();
    //用Decoder对象对加密之后的文件进行解密
    result = decoder.decode(result);
    System.out.println("将result解码之后:"+new String(result));
}
public static void commonsCodecBase64(){
    //commonscodec的方便之处在于直接用Base64.encoderBase64和Base64.decoderBase64进行加解密
    //加密
    byte[] result = org.apache.commons.codec.binary.Base64.encodeBase64(src.getBytes());
    System.out.println("Base64编码之后:"+new String(result));
    //解密
    result = org.apache.commons.codec.binary.Base64.decodeBase64(result);
    System.out.println("Base64解密之后:"+new String(result));
}
public static void bouncyCastleBase64(){
     //加密
    byte[] result = org.bouncycastle.util.encoders.Base64.encode(src.getBytes());
    System.out.println("Base64编码之后:"+new String(result));
    //解密
    result = org.bouncycastle.util.encoders.Base64.decode(result);
    System.out.println("Base64解密之后:"+new String(result));
}

//运行结果如下
/*
        =====jdkBase64编码测试=====
        Base64编码之后::aSBhbSBnYyBiYXNlNjQ=
        将result解码之后:i am gc base64
        ==========================
        =====CommonsCodec的Base64实现=====
        Base64编码之后:aSBhbSBnYyBiYXNlNjQ=
        Base64解密之后:i am gc base64
        ==========================
        =====BouncyCastle的Base64实现=====
        Base64编码之后:aSBhbSBnYyBiYXNlNjQ=
        Base64解密之后:i am gc base64
        ==========================
 */
}

其实无论是bc或者cc都提供了static方法对Base64加解密进行很好的操作支持
不建议使用jdk提供的方法进行操作

2.3 Base64应用场景

base64其实不算是加密,可以说是一种转码.比如对一些特殊字符的处理; 对文件内容的转码等.


3 消息摘要–MD

3.1 介绍

MD家族包括MD2, MD4, MD5,他们生成的消息摘要都是128位. 安全性上的比较也是越来越安全.
JDK仅仅提供了MD2,MD5的实现.

3.2 代码实现
package secret;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import org.apache.commons.codec.binary.Hex;
import org.apache.commons.codec.digest.DigestUtils;
import org.bouncycastle.crypto.Digest;
import org.bouncycastle.crypto.digests.MD4Digest;
import org.bouncycastle.crypto.digests.MD5Digest;

public class MDTest {
public static String src = "i am gc MD";
public static void main(String[] args) {
    System.out.println("=====jdk提供的MD5=====");
    jdkMD5();
    System.out.println("=====================");
    System.out.println("=====jdk提供的MD2=====");
    jdkMD2();
    System.out.println("=====================");
    System.out.println("=====BC提供的MD4=====");
    bcMD4();
    System.out.println("=====================");
    System.out.println("=====BC提供的MD5=====");
    bcMD5();
    System.out.println("=====================");
    System.out.println("=====CC提供的MD5=====");
    ccMD5();
    System.out.println("=====================");
    System.out.println("=====CC提供的MD2=====");
    ccMD2();
    System.out.println("=====================");


    //运行结果
    /*=====jdk提供的MD5=====
        信息摘要之后的src: 8a63f68d49d7acfa716602e9ab620394
        =====================
        =====jdk提供的MD2=====
        信息摘要之后的src: 2d2df5c04ceeaac31bdffb019ccd03c8
        =====================
        =====BC提供的MD4=====
        信息摘要之后的src: 5ff5d77df559660ed4ff19ac2f5e2e2a
        =====================
        =====BC提供的MD5=====
        信息摘要之后的src: 8a63f68d49d7acfa716602e9ab620394
        =====================
        =====CC提供的MD5=====
        信息摘要之后的src: 8a63f68d49d7acfa716602e9ab620394
        =====================
        =====CC提供的MD2=====
        信息摘要之后的src: 2d2df5c04ceeaac31bdffb019ccd03c8
        =====================
     */
}
/*
 * jdkMD5方法
 */
public static void jdkMD5(){
    try {
        //jdk提供的MessageDegest类 创建对象时候需要传入参数,可以是MD5, MD2
        MessageDigest md = MessageDigest.getInstance("MD5");
        byte[] result = md.digest(src.getBytes());
        //因为digest方法返回的使一个byte数组,如果想输出字符串,必须将byte数组转化成16进制等,但是jdk并没有提供这样的方法,所以你可以选择自己写或者使用bc或cc提供的方法
        //现在我们借助cc提供的方法
        //输出32位16进制数
        System.out.println("信息摘要之后的src: "+Hex.encodeHexString(result));
    } catch (Exception e) {
        e.printStackTrace();
    }
}
/*
 * jdkMD2信息摘要
 */
public static void jdkMD2(){
    try {
        //jdk提供的MessageDegest类 创建对象时候需要传入参数,可以是MD5, MD2
        MessageDigest md = MessageDigest.getInstance("MD2");
        byte[] result = md.digest(src.getBytes());
        //因为digest方法返回的使一个byte数组,如果想输出字符串,必须将byte数组转化成16进制等,但是jdk并没有提供这样的方法,所以你可以选择自己写或者使用bc或cc提供的方法
        //现在我们借助cc提供的方法
        //输出32位16进制数
        System.out.println("信息摘要之后的src: "+Hex.encodeHexString(result));
    } catch (Exception e) {
        e.printStackTrace();
    }
}

//bc实现MD4
public static void bcMD4(){
    //Digest是一个借口,MD4Degist仅仅是一个实现类
    Digest digest = new MD4Digest();
    //进行摘要
    digest.update(src.getBytes(), 0 , src.getBytes().length);
    //获取算法摘要出来的长度
    byte[] result = new byte[digest.getDigestSize()];
    //摘要的输出到变量里
    digest.doFinal(result, 0);
    //进行转换输出
    System.out.println("信息摘要之后的src: "+Hex.encodeHexString(result));
}

/*
 * bc实现MD5
 * 跟bc实现MD4相似,在此不再加注释
 */
public static void bcMD5(){
    Digest digest = new MD5Digest();
    digest.update(src.getBytes(), 0, src.getBytes().length);
    byte[] result = new byte[digest.getDigestSize()];
    digest.doFinal(result, 0);
    System.out.println("信息摘要之后的src: "+Hex.encodeHexString(result));
}

/*
 * cc对MD5的实现
 */
public static void ccMD5(){
    //说实话.CC提供的DegistUtils工具类对信息摘要的实现真的是简单至极
    String result = DigestUtils.md5Hex(src.getBytes());
    System.out.println("信息摘要之后的src: "+result);
}
/*
 * cc对MD2的实现
 */
public static void ccMD2(){
    //说实话.CC提供的DegistUtils工具类对信息摘要的实现真的是简单至极
    //但是CC做了个偷工减料的地方,CC仅仅是对jdk中MessageDegist的简单包装,所以CC中支持md4的实现
    String result = DigestUtils.md2Hex(src.getBytes());
    System.out.println("信息摘要之后的src: "+result);
}
}
3.3 MD5的应用

可以对用户注册的注册密码进行MD5消息摘要处理,然后再存数据库.当用户登陆时候,对用户输入的密码再次进行MD5,之后在与数据库中的MD5码进行比对.这样能够很好的对密码进行保护.但是要记住:MD5仅仅是单向的,不可逆的.


4 SHA消息摘要

4.1 介绍

SHA是一种安全散列算法,也是固定长度的消息摘要. 包括:SHA-1, SHA-2(SHA-224,SHA-256, SHA-384, SHA-512)
她是在MD4演变出来的

SHA-224等等后面的数字都使摘要的长度,比如SHA-224摘要出来的长度就是224位
这里面只有SHA-224 jdk没有提供实现

4,2 代码实现
package secret;

import java.security.MessageDigest;

import org.apache.commons.codec.binary.Hex;
import org.apache.commons.codec.digest.DigestUtils;
import org.bouncycastle.crypto.Digest;
import org.bouncycastle.crypto.digests.SHA1Digest;
import org.bouncycastle.crypto.digests.SHA224Digest;

public class SHATest {
    public static String src = "i am gc SHA";

    public static void main(String[] args) {
        System.out.println("=====jdk提供的SHA1=====");
        jdkSHA1();
        System.out.println("=====================");
        System.out.println("=====bc提供的SHA1=====");
        bcSHA1();
        System.out.println("=====================");
        System.out.println("=====cc提供的SHA1=====");
        ccSHA1();
        System.out.println("=====================");
        System.out.println("=====bc提供的SHA-256=====");
        jdkSHA256();
        System.out.println("=====================");
        System.out.println("=====bc提供的SHA224=====");
        bcSHA224();
        System.out.println("=====================");

        //运行结果
        /*
            =====jdk提供的SHA1=====
            消息摘要之后:02470457fc2738acb459ee266dd66976324ee5b8
            =====================
            =====bc提供的SHA1=====
            消息摘要之后:02470457fc2738acb459ee266dd66976324ee5b8
            =====================
            =====cc提供的SHA1=====
            消息摘要之后:02470457fc2738acb459ee266dd66976324ee5b8
            =====================
            =====bc提供的SHA-256=====
            消息摘要之后:dd855bed3dce767ad1ce3f051b8d6fba12a0c00fe2feaa142ca37f2ae88fbca3
            =====================
            =====bc提供的SHA224=====
            消息摘要之后:f2a63bc30d2d8fcebc9b5aa4f660b6f422328731588346dbd55a1a2f
            =====================
         */
    }

    /*
     * jdk对SHA算法实现
     */
    public static void jdkSHA1() {
        try {
            byte[] result;
            MessageDigest digest = MessageDigest.getInstance("SHA1");
            result = digest.digest(src.getBytes());
            System.out.println("消息摘要之后:" + Hex.encodeHexString(result));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /*
     * bc实现SHA1
     */
    public static void bcSHA1() {
        // 因为都是用Digest接口里的方法,在MD代码里已经注释了,这里就不再叙述
        Digest digest = new SHA1Digest();
        digest.update(src.getBytes(), 0, src.getBytes().length);
        byte[] result = new byte[digest.getDigestSize()];
        digest.doFinal(result, 0);
        System.out.println("消息摘要之后:" + Hex.encodeHexString(result));
    }

    /*
     * jdk对SHA-256的支持
     */
    public static void jdkSHA256() {
        try {
            byte[] result;
            MessageDigest digest = MessageDigest.getInstance("SHA-256");
            result = digest.digest(src.getBytes());
            System.out.println("消息摘要之后:" + Hex.encodeHexString(result));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /*
     * bc实现SHA224
     */
    public static void bcSHA224() {
        // 因为都是用Digest接口里的方法,在MD代码里已经注释了,这里就不再叙述
        Digest digest = new SHA224Digest();
        digest.update(src.getBytes(), 0, src.getBytes().length);
        byte[] result = new byte[digest.getDigestSize()];
        digest.doFinal(result, 0);
        System.out.println("消息摘要之后:" + Hex.encodeHexString(result));
    }

    /*
     * cc对SHA1的实现
     * 其实也是对jdk的包装
     */
    public static void ccSHA1(){
        String result = DigestUtils.sha1Hex(src.getBytes());
        System.out.println("消息摘要之后:" +result);
    }
    /*
     * 其余的SHA实现都与上面的方法相同
     */
}
4.3 应用

一些证书中的指纹摘要
对发送的消息进行验证,消息是否被篡改


  • 文章中避免不了错误的出现,如果有读者发现文章中的错误,或者有疑问的地方,请留言/Email To Gc
  • 请转发OR复制的同学,标注出处,尊重作者劳动成果,谢谢亲

博客地址迁移至 int32.me

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值