1. 本周计划完成的任务
  2. 本周实际完成情况(代码,文档,程序运行截图…),未完成计划的原因?如何改进?
  3. 本周遇到的问题与解决过程(要详细)

本周计划完成的任务

  1. 给openeuler配置java语言环境

  2. 在windows下配置maven工具

  3. 编写代码,调通测试基于java语言的国密算法库-bouncycastle

  4. 在windows下的idea中使用maven,分别对sm2、sm3、sm4的测试项目进行打包,并在linux下运行

本周实际完成情况

第一项任务:“给openeuler配置java语言环境,学会linux下的java程序的编译方法”,已顺利完成

第二项任务:“学习java项目打包工具maven,在linux配置maven工具”,已顺利完成

Maven的作用

关于maven的作用,我在b站看了一节尚硅谷的讲座,虽然尚硅谷的老师是围绕着大型java-web开发的应用来讲解maven要解决的问题的,但我还是有很大的收获。

https://www.bilibili.com/video/BV1TW411g7hP/

目前的技术在开发中存在的问题

1. 一个项目就是一个工程,如果项目非常庞大,就不适合继续使用package来划分模块。最好是每一个模块对应一个工程,利于
分工协作。
借助于Maven就可以将一个项目拆分成多个工程。

2. 项目中需要的jar包必须手动“复制”、“粘贴”到WEB-INF/ib目录下,带来的问题是:同样的jr包文件重复出现在不同的项目工程中。

借助Maven,可以将jar包仅仅保存在”仓库”中,有需要使用的工程“引用”这个文件接口,并不需要真的把jar包复制过来。

3. jar包需要别人替我们准备好,或到官网下载
不同技术的官网提供包下载的形式是五花八门的。
有些技术的官网就是通过Maven或SVN等专门的工具来提供下载的。
如果是以不规范的方式下载的jr包,那么其中的内容很可能也是不规范的。
借助于Maven可以以一种规范的方式下载jar包。因为所有知名框架或第三方工具的jar包以及按照统一的规范存放在了Maven的中央仓库中。
以规范的方式下载的jar包,内容也是可靠的。

PS:“统一的规范”不仅是对IT开发领域非常重要,对于整个人类社会都是非常重要的。

4. 一个jar包依赖的其他jar包需要自己手动加入到项目中

FileUploads组件依赖于IO组件。commons-fileupload-l.3.jar依赖于commons-io-2.0.1jar。
如果所有r包之间的依赖关系都需要程序员自己非常清楚的了解,那么就会极大的增加学习成本。
Maven会自动将被依赖的jar包导入进来。

Maven是什么?

Maven是一款服务于Java平台的自动化构建工具
Make-Ant→Maven→Gradle
顺便整理一下构建项目的概念

  • 概念:以“Java源文件”、“框架配置文件”、“JSP、“HTML”、“图片”等资源为“原材料”,去“生产”一个可以运行的项目的过程。
    分为三个环节:
    编译
    部署
    搭建
  • 编译:Java源文件User.java→编译→Class字节码文[User.class]交给JVM去执行
  • 部署:一个BS项目最终运行的并不是动态Wb工程本身,而是这个动态Wb工程”编译的结果”

生的鸡→处理→熟的鸡
动态Web工程→编译、部署→编译结果

  • 构建
    [1]清理:将以前编泽得到的旧的clSs字节码文件别除,为下一次编译做准备
    [2]编译:将)ava源程序编程成class字节码文件
    [3]测试:自动测试,自动调用junit程序
    [4报告:测试程序执行的结果
    [5]打包:动态Web工程打war包,Java工程打jar包
    [6]安装:Maven特定的概念—将打包得到的文件复制到“仓库”中的指定位置
    [7]部署:将动态Web工程生成的war包复制到Servlets容器的指定目录下,使其可以运行

配置maven环境

在官网下载Maven

解压至非中文无空格目录

配置Maven环境变量

系统变量:MAVEN_HOME

同时把它加入到环境变量Path中

验证Maven是否可用

使用mvn -v查看版本,出现以下信息则安装成功

配置本地仓库位置

配置阿里云镜像加速

修改config/setting.xml文件

第三项任务:“调通基于java语言的国密算法库-bouncycastle”

完成情况:我完成了支持国密算法的bouncycastle算法库的下载和使用。

首先去bouncycastle官网查看匹配jdk18版本的相应bouncycastle版本

编写测试主类代码和加密工具类的代码

基于java语言的算法库测试,以sm2为例,我们首先需要将密码库中跟sm2有关的方法进行实例化,也就是专门写一个SM2Util.java这样的类,里面包含所有我们需要用到的方法。

SM2

sm2Util.java

package sm2;
import org.bouncycastle.crypto.engines.SM2Engine;
import org.bouncycastle.crypto.params.*;
import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey;
import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey;
import org.bouncycastle.jce.spec.ECParameterSpec;
import org.bouncycastle.util.encoders.Hex;

import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;

public class SM2Util {
    /**
     * SM2加密算法
     * @param publicKey     公钥
     * @param data          明文数据
     * @return
     */
    public String encrypt(PublicKey publicKey, String data) {

        ECPublicKeyParameters ecPublicKeyParameters = null;
        if (publicKey instanceof BCECPublicKey) {
            BCECPublicKey bcecPublicKey = (BCECPublicKey) publicKey;
            ECParameterSpec ecParameterSpec = bcecPublicKey.getParameters();
            ECDomainParameters ecDomainParameters = new ECDomainParameters(ecParameterSpec.getCurve(),
                    ecParameterSpec.getG(), ecParameterSpec.getN());
            ecPublicKeyParameters = new ECPublicKeyParameters(bcecPublicKey.getQ(), ecDomainParameters);
        }

        SM2Engine sm2Engine = new SM2Engine();
        sm2Engine.init(true, new ParametersWithRandom(ecPublicKeyParameters, new SecureRandom()));

        byte[] arrayOfBytes = null;
        try {
            byte[] in = data.getBytes("utf-8");
            arrayOfBytes = sm2Engine.processBlock(in,0, in.length);
        } catch (Exception e) {
            System.out.println("SM2加密时出现异常:");
        }
        return Hex.toHexString(arrayOfBytes);
    }

    /**
     * SM2解密算法
     * @param privateKey        私钥
     * @param cipherData        密文数据
     * @return
     */
    public String decrypt(PrivateKey privateKey, String cipherData) {
        byte[] cipherDataByte = Hex.decode(cipherData);

        BCECPrivateKey bcecPrivateKey = (BCECPrivateKey) privateKey;
        ECParameterSpec ecParameterSpec = bcecPrivateKey.getParameters();

        ECDomainParameters ecDomainParameters = new ECDomainParameters(ecParameterSpec.getCurve(),
                ecParameterSpec.getG(), ecParameterSpec.getN());

        ECPrivateKeyParameters ecPrivateKeyParameters = new ECPrivateKeyParameters(bcecPrivateKey.getD(),
                ecDomainParameters);

        SM2Engine sm2Engine = new SM2Engine();
        sm2Engine.init(false, ecPrivateKeyParameters);

        String result = null;
        try {
            byte[] arrayOfBytes = sm2Engine.processBlock(cipherDataByte, 0, cipherDataByte.length);
            return new String(arrayOfBytes, "utf-8");
        } catch (Exception e) {
            System.out.println("SM2解密时出现异常");
        }
        return result;
    }
}

主类测试代码

package sm2;

import org.bouncycastle.jce.provider.BouncyCastleProvider;
import java.security.*;
import java.security.spec.ECGenParameterSpec;

public class sm2_demo {
    private static String M="sm2_demo";
    public static void main(String[] args) throws NoSuchAlgorithmException, InvalidAlgorithmParameterException {
        SM2Util sm2 = new SM2Util();
        final ECGenParameterSpec sm2Spec = new ECGenParameterSpec("sm2p256v1");
        // 获取一个椭圆曲线类型的密钥对生成器
        final KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC", new BouncyCastleProvider());
        // 使用SM2参数初始化生成器
        kpg.initialize(sm2Spec);
        // 获取密钥对
        KeyPair keyPair = kpg.generateKeyPair();
        PublicKey publicKey = keyPair.getPublic();
        PrivateKey privateKey = keyPair.getPrivate();
        String data = sm2.encrypt(publicKey,M);
        System.out.println("明文:"+M);
        System.out.println("密文:"+data);
        String text=sm2.decrypt(privateKey,data);
        System.out.println("解密结果"+text);
    }
}

SM3

SM3测试主类

package sm3;

import sm3.SM3Util;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import java.security.*;
import java.security.spec.ECGenParameterSpec;

public class sm3_demo {
    private static String test="SM3_demo";
    public static void main(String[] args) throws NoSuchAlgorithmException,
            InvalidAlgorithmParameterException {
        SM3Util sm3 = new SM3Util();
        String data = sm3.plainEncrypt(test);
        System.out.println("明文:"+test);
        System.out.println("哈希值:"+data);
    }
}

SM3Util.java

package sm3;

import org.bouncycastle.crypto.digests.SM3Digest;
import org.bouncycastle.crypto.macs.HMac;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.util.encoders.Hex;

import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;

/**
 * @Author: dzy
 * @Date: 2018/10/19 16:36
 * @Describe: SM3工具类(杂凑算法-hash算法)
 */

public class SM3Util {

    /**
     * 16进制字符串SM3生成HASH签名值算法
     * @param hexString     16进制字符串
     * @return
     */
    public static String hexEncrypt(String hexString) {
        byte[] srcData = Hex.decode(hexString);
        byte[] encrypt = encrypt(srcData);
        String cipherStr  = Hex.toHexString(encrypt);
        return cipherStr;
    }

    /**
     * 16进制字符串SM3生成HASH签名值算法
     * @param hexKey        16进制密钥
     * @param hexString     16进制字符串
     * @return
     */
    public static String hexEncrypt(String hexKey, String hexString) {
        byte[] key = Hex.decode(hexKey);
        byte[] srcData = Hex.decode(hexString);
        byte[] encrypt = encrypt(key, srcData);
        String cipherStr  = Hex.toHexString(encrypt);
        return cipherStr;
    }

    /**
     * 普通文本SM3生成HASH签名算法
     * @param plain     待签名数据
     * @return
     */
    public static String plainEncrypt(String plain) {
        // 将返回的hash值转换成16进制字符串
        String cipherStr = null;
        try {
            //将字符串转换成byte数组
            byte[] srcData = plain.getBytes(StandardCharsets.UTF_8);
            //调用encrypt计算hash
            byte[] encrypt = encrypt(srcData);
            //将返回的hash值转换成16进制字符串
            cipherStr = Hex.toHexString(encrypt);
        } catch (Exception e) {
            //log.error("将字符串转换为字节时出现异常:", e);
        }
        return cipherStr;
    }

    /**
     * 普通文本SM3生成HASH签名算法
     * @param hexKey        密钥
     * @param plain         待签名数据
     * @return
     */
    public static String plainEncrypt(String hexKey, String plain) {
        // 将返回的hash值转换成16进制字符串
        String cipherStr = null;
        try {
            //将字符串转换成byte数组
            byte[] srcData = plain.getBytes(StandardCharsets.UTF_8);
            //密钥
            byte[] key = Hex.decode(hexKey);
            //调用encrypt计算hash
            byte[] encrypt = encrypt(key, srcData);
            //将返回的hash值转换成16进制字符串
            cipherStr = Hex.toHexString(encrypt);
        } catch (Exception e) {
            //log.error("将字符串转换为字节时出现异常:", e);
        }
        return cipherStr;
    }

    /**
     * SM3计算hashCode
     * @param srcData   待计算数据
     * @return
     */
    public static byte[] encrypt(byte[] srcData) {
        SM3Digest sm3Digest = new SM3Digest();
        sm3Digest.update(srcData, 0, srcData.length);
        byte[] encrypt = new byte[sm3Digest.getDigestSize()];
        sm3Digest.doFinal(encrypt, 0);
        return encrypt;
    }

    /**
     * 通过密钥进行加密
     * @param key       密钥byte数组
     * @param srcData   被加密的byte数组
     * @return
     */
    public static byte[] encrypt(byte[] key, byte[] srcData) {
        KeyParameter keyParameter = new KeyParameter(key);
        SM3Digest digest = new SM3Digest();
        HMac mac = new HMac(digest);
        mac.init(keyParameter);
        mac.update(srcData, 0, srcData.length);
        byte[] result = new byte[mac.getMacSize()];
        mac.doFinal(result, 0);
        return result;
    }

    /**
     * SM3计算hashCode
     * @param srcData   待计算数据
     * @return
     * @throws Exception
     */
    public static byte[] encrypt_0(byte[] srcData) throws Exception {
        MessageDigest messageDigest = MessageDigest.getInstance("SM3", "BC");
        byte[] digest = messageDigest.digest(srcData);
        return digest;
    }

}

SM4

SM4测试主类

package sm4;

import java.security.*;
import java.security.spec.ECGenParameterSpec;
public class sm4_demo {
    private static String test= "SM4_test_zhl1321";
    private static String mykey= "6cef39eb85614df44f6b0f6babcd89b6";
    public static void main(String[] args) throws NoSuchAlgorithmException,
            InvalidAlgorithmParameterException {
        SM4Util sm4 = new SM4Util();
        //SM3Util sm3 = new SM3Util();
        //String data_in = sm3.plainEncrypt(test);
        //String data = sm4.encryptByEcb(data_in,mykey);
        String x16 = sm4.strToHexadecimal(test);
        //System.out.println(x16);
        String data = sm4.encryptByEcb(x16,mykey);
        System.out.println("明文:"+test);
        //System.out.println("摘   要:"+data_in);
        System.out.println("密文:"+data);
        String text_16 = sm4.decryptByEcb(data,mykey);
        //System.out.println(text_16);
        //System.out.println(x16.equals(text_16.toUpperCase()));
        String text = sm4.hexadecimalToStr(text_16.toUpperCase());
        System.out.println("解密结果:"+text);
    }
}

SM4Util.java

package sm4;

import org.bouncycastle.crypto.engines.SM4Engine;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.util.encoders.Hex;

/**
 * @Author: dzy
 * @Date: 2018/10/9 16:41
 * @Describe: SM4算法
 */
public class SM4Util {

    //加解密的字节快大小
    public static final int BLOCK_SIZE = 16;

    /**
     * SM4ECB加密算法
     * @param in            待加密内容
     * @param keyBytes      密钥
     * @return
     */
    public static byte[] encryptByEcb0(byte[] in, byte[] keyBytes) {
        SM4Engine sm4Engine = new SM4Engine();
        sm4Engine.init(true, new KeyParameter(keyBytes));
        int inLen = in.length;
        byte[] out = new byte[inLen];

        int times = inLen / BLOCK_SIZE;

        for (int i = 0; i < times; i++) {
            sm4Engine.processBlock(in, i * BLOCK_SIZE, out, i * BLOCK_SIZE);
        }

        return out;
    }

    /**
     * SM4ECB加密算法
     * @param in            待加密内容
     * @param keyBytes      密钥
     * @return
     */
    public static String encryptByEcb(byte[] in, byte[] keyBytes) {
        byte[] out = encryptByEcb0(in, keyBytes);
        String cipher = Hex.toHexString(out);
        return cipher;
    }

    /**
     * SM4的ECB加密算法
     * @param content   待加密内容
     * @param key       密钥
     * @return
     */
    public static String encryptByEcb(String content, String key) {
        byte[] in = Hex.decode(content);
        byte[] keyBytes = Hex.decode(key);

        String cipher = encryptByEcb(in, keyBytes);
        return cipher;
    }

    /**
     * SM4的ECB解密算法
     * @param in        密文内容
     * @param keyBytes  密钥
     * @return
     */
    public static byte[] decryptByEcb0(byte[] in, byte[] keyBytes) {
        SM4Engine sm4Engine = new SM4Engine();
        sm4Engine.init(false, new KeyParameter(keyBytes));
        int inLen = in.length;
        byte[] out = new byte[inLen];

        int times = inLen / BLOCK_SIZE;

        for (int i = 0; i < times; i++) {
            sm4Engine.processBlock(in, i * BLOCK_SIZE, out, i * BLOCK_SIZE);
        }

        return out;
    }

    /**
     * SM4的ECB解密算法
     * @param in        密文内容
     * @param keyBytes  密钥
     * @return
     */
    public static String decryptByEcb(byte[] in, byte[] keyBytes) {
        byte[] out = decryptByEcb0(in, keyBytes);
        String plain = Hex.toHexString(out);
        return plain;
    }

    /**
     * SM4的ECB解密算法
     * @param cipher    密文内容
     * @param key       密钥
     * @return
     */
    public static String decryptByEcb(String cipher, String key) {
        byte[] in = Hex.decode(cipher);
        byte[] keyBytes = Hex.decode(key);

        String plain = decryptByEcb(in, keyBytes);
        return plain;
    }

    public static String strToHexadecimal(String str) {
        char[] chars = "0123456789ABCDEF".toCharArray();
        StringBuilder sb = new StringBuilder("");
        byte[] bs = str.getBytes();
        int bit;
        for (int i = 0; i < bs.length; i++) {
            bit = (bs[i] & 0x0f0) >> 4;
            sb.append(chars[bit]);
            bit = bs[i] & 0x0f;
            sb.append(chars[bit]);
        }
        return sb.toString().trim();
    }

    public static String hexadecimalToStr(String hexStr) {
        String str = "0123456789ABCDEF";
        char[] hexs = hexStr.toCharArray();
        byte[] bytes = new byte[hexStr.length() / 2];
        int n;
        for (int i = 0; i < bytes.length; i++) {
            n = str.indexOf(hexs[2 * i]) * 16;
            n += str.indexOf(hexs[2 * i + 1]);
            bytes[i] = (byte) (n & 0xff);
        }
        return new String(bytes);
    }
}

运行结果

此处我们还需要写一个maven配置文件,pom.xml,注明本项目依赖bouncycastle的jar包,写明这个依赖关系,我们就不需要自己亲自动手去下jar包和配置

在配置文件pom.xml中加入依赖关系:

    <dependencies>
        <dependency>
            <groupId>org.bouncycastle</groupId>
            <artifactId>bcprov-jdk18on</artifactId>
            <version>1.72</version>
        </dependency>
        <dependency>
            <groupId>org.bouncycastle</groupId>
            <artifactId>bcprov-ext-jdk18on</artifactId>
            <version>1.72</version>
        </dependency>
    </dependencies>

并且在idea中需要手动加载这些依赖项,每次都会忘记,会导致bouncycastle还是会爆红

用maven打包项目

参考博客
https://blog.csdn.net/londa/article/details/115098901

其中我是用第二种方式,即使用maven-assembly-plugin插件打包的。
在pom.xml加上

    <build>
        <finalName>sm2test</finalName><!--修改编译出来的jar包名,仅为{artifactId}.jar-->
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-assembly-plugin</artifactId>
                <version>2.5.5</version>
                <configuration>
                    <archive>
                        <manifest>
                            <mainClass>sm2.sm2_demo</mainClass>
                        </manifest>
                    </archive>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                </configuration>
            </plugin>
        </plugins>
    </build>

然后在terminal下cd到项目目录,
运行mvn package assembly:single

出现BUILD SUCCESS即说明打包成功,在external libraries下会出现相应的jar包,此时用java -jar xxx.jar可以运行该jar包

接着在linux环境下运行jar包

将jar包放到工作文件夹下,使用java jar xxx.jar即可运行


遇到的问题以及如何解决?

linux和windows环境的jdk版本不匹配产生了兼容性问题

当我试图在linux下运行我在windows环境中创建的jar包时,提示以下问题:

意识到应该是jdk版本问题,故用java -version查看发现确实不匹配

——也就是说,我们想在linux环境下运行在windows环境中用maven工具打包好的jar包,就需要linux环境下的jdk版本和windows中编译项目用的jdk版本一致。

所以之后参考博客重新下载了跟windows里面版本相同的jdk包,并且修改了环境变量,删掉了原来的配置文件,以及有一个重要步骤是要建立新链接:

ln -s $JAVA HOME/bin/javac /usr/bin/javac
ln -s $JAVA HOME/bin/java /usr/bin/java

不然还是会识别不了。

maven打包时,主类入口没写对


一开始这么写是不对的,是主类,而不是main方法,所以只要写到sm2(package).sm2_demo(类名)就可以了。

maven打包出现“无法初始化主类”错误,而且打出的jar包只有5kb,正常情况下应该是5~15mb左右


一开始是使用maven-jar-plugin和maven-dependency-plugin插件打包,就会出现这种错误,后面换成使用使用maven-assembly-plugin插件打包就成功了。

参考https://blog.csdn.net/sdrfengmi/article/details/87191944

原文地址:http://www.cnblogs.com/zhou-huilin/p/16926035.html

1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长! 2. 分享目的仅供大家学习和交流,请务用于商业用途! 3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入! 4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解! 5. 如有链接无法下载、失效或广告,请联系管理员处理! 6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需! 7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员! 8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载 声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性