Android 数据SM4传输加解密

这篇具有很好参考价值的文章主要介绍了Android 数据SM4传输加解密。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

第一:场景介绍

  甲方要求,数据在传输过程中要加密。

第二:选择加解密方式:

这里面Android 和服务端都是选择SM4

第三:实现方式

1:服务端采用SpringBoot,在pom.xml 文件下添加依赖

		<dependency>
			<groupId>org.bouncycastle</groupId>
			<artifactId>bcprov-jdk15on</artifactId>
			<version>1.64</version>
		</dependency>

2:在Android 端同样添加依赖,在module 下面build.gradle

  implementation group: 'org.bouncycastle', name: 'bcprov-jdk15on', version: '1.64'

3:服务端SM4工具类

package com.wansun.datahouse.visit.utils;

import org.apache.tomcat.util.buf.HexUtils;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.SecureRandom;
import java.security.Security;

/**
 * TODO:
 * 国密SM4算法
 *
 * @author Blade
 * @date 2022/5/9 17:13
 */
public class Sm4Util {

    /**
     * 算法名称
     */
    public static final String ALGORITHM_NAME = "SM4";

    /**
     * SM4算法ECB模式PKCS5Padding填充方式
     */
    public static final String ALGORITHM_NAME_ECB_PADDING = "SM4/ECB/PKCS5Padding";

    /**
     * SM4算法ECB模式不填充
     */
    public static final String ALGORITHM_NAME_ECB_NOPADDING = "SM4/ECB/NoPadding";

    /**
     * SM4算法CBC模式PKCS5Padding填充方式
     */
    public static final String ALGORITHM_NAME_CBC_PADDING = "SM4/CBC/PKCS5Padding";

    /**
     * SM4算法CBC模式不填充
     */
    public static final String ALGORITHM_NAME_CBC_NOPADDING = "SM4/CBC/NoPadding";

    /**
     * 默认key长度
     */
    public static final int DEFAULT_KEY_SIZE = 128;

    static {
        // 加入 BC 实现
        Security.addProvider(new BouncyCastleProvider());
    }

    /**
     * 生成秘钥 key
     *
     * @return key
     * @throws NoSuchAlgorithmException 异常
     * @throws NoSuchProviderException  异常
     */
    private static byte[] generateKey() throws NoSuchAlgorithmException, NoSuchProviderException {
        return generateKey(DEFAULT_KEY_SIZE);
    }

    /**
     * 生成秘钥 key
     *
     * @param keySize 秘钥长度
     * @return key
     * @throws NoSuchAlgorithmException 异常
     * @throws NoSuchProviderException  异常
     */
    private static byte[] generateKey(int keySize) throws NoSuchAlgorithmException, NoSuchProviderException {
        KeyGenerator kg = KeyGenerator.getInstance(ALGORITHM_NAME, BouncyCastleProvider.PROVIDER_NAME);
        kg.init(keySize, new SecureRandom());
        return kg.generateKey().getEncoded();
    }

    /**
     * 生成ECB模式的cipher
     *
     * @param algorithmName 算法名称
     * @param mode          模式
     * @param key           秘钥
     * @return {@link Cipher} 密文
     * @throws NoSuchAlgorithmException 异常
     * @throws NoSuchProviderException  异常
     * @throws NoSuchPaddingException   异常
     * @throws InvalidKeyException      异常
     */
    private static Cipher generateEcbCipher(String algorithmName, int mode, byte[] key)
            throws NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException,
            InvalidKeyException {
        Cipher cipher = Cipher.getInstance(algorithmName, BouncyCastleProvider.PROVIDER_NAME);
        Key sm4Key = new SecretKeySpec(key, ALGORITHM_NAME);
        cipher.init(mode, sm4Key);
        return cipher;
    }

    /**
     * 用ECB模式和PKCS5Padding填充的方式 进行加密
     *
     * @param key  秘钥
     * @param data 加密前的数据
     * @return 加密后的数据
     * @throws InvalidKeyException       异常
     * @throws NoSuchAlgorithmException  异常
     * @throws NoSuchProviderException   异常
     * @throws NoSuchPaddingException    异常
     * @throws IllegalBlockSizeException 异常
     * @throws BadPaddingException       异常
     */
    private static byte[] encryptEcbPadding(byte[] key, byte[] data)
            throws InvalidKeyException, NoSuchAlgorithmException, NoSuchProviderException,
            NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException {
        Cipher cipher = generateEcbCipher(ALGORITHM_NAME_ECB_PADDING, Cipher.ENCRYPT_MODE, key);
        return cipher.doFinal(data);
    }

    /**
     * 用ECB模式和PKCS5Padding填充的方式 进行解密
     *
     * @param key        秘钥
     * @param cipherText 加密后的数据
     * @return 解密后的数据
     * @throws InvalidKeyException       异常
     * @throws NoSuchAlgorithmException  异常
     * @throws NoSuchProviderException   异常
     * @throws NoSuchPaddingException    异常
     * @throws IllegalBlockSizeException 异常
     * @throws BadPaddingException       异常
     */
    private static byte[] decryptEcbPadding(byte[] key, byte[] cipherText)
            throws IllegalBlockSizeException, BadPaddingException, InvalidKeyException,
            NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException {
        Cipher cipher = generateEcbCipher(ALGORITHM_NAME_ECB_PADDING, Cipher.DECRYPT_MODE, key);
        return cipher.doFinal(cipherText);
    }


    /**
     * 用ECB模式和不填充的方式 进行加密
     *
     * @param key  秘钥
     * @param data 加密前的数据
     * @return 加密后的数据
     * @throws InvalidKeyException       异常
     * @throws NoSuchAlgorithmException  异常
     * @throws NoSuchProviderException   异常
     * @throws NoSuchPaddingException    异常
     * @throws IllegalBlockSizeException 异常
     * @throws BadPaddingException       异常
     */
    private static byte[] encryptEcbNoPadding(byte[] key, byte[] data)
            throws InvalidKeyException, NoSuchAlgorithmException, NoSuchProviderException,
            NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException {
        Cipher cipher = generateEcbCipher(ALGORITHM_NAME_ECB_NOPADDING, Cipher.ENCRYPT_MODE, key);
        return cipher.doFinal(data);
    }

    /**
     * 用ECB模式和不填充的方式 进行解密
     *
     * @param key        秘钥
     * @param cipherText 解密前的数据
     * @return 解密后的数据
     * @throws InvalidKeyException       异常
     * @throws NoSuchAlgorithmException  异常
     * @throws NoSuchProviderException   异常
     * @throws NoSuchPaddingException    异常
     * @throws IllegalBlockSizeException 异常
     * @throws BadPaddingException       异常
     */
    private static byte[] decryptEcbNoPadding(byte[] key, byte[] cipherText)
            throws IllegalBlockSizeException, BadPaddingException, InvalidKeyException,
            NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException {
        Cipher cipher = generateEcbCipher(ALGORITHM_NAME_ECB_NOPADDING, Cipher.DECRYPT_MODE, key);
        return cipher.doFinal(cipherText);
    }

    /**
     * 生成CBC模式的cipher
     *
     * @param algorithmName 算法名称
     * @param mode          模式
     * @param key           秘钥
     * @param iv            偏移量(自定义的字符串)
     * @return {@link Cipher}
     * @throws NoSuchAlgorithmException 异常
     * @throws NoSuchProviderException  异常
     * @throws NoSuchPaddingException   异常
     * @throws InvalidKeyException      异常
     */
    private static Cipher generateCbcCipher(String algorithmName, int mode, byte[] key, byte[] iv)
            throws InvalidKeyException, InvalidAlgorithmParameterException, NoSuchAlgorithmException,
            NoSuchProviderException, NoSuchPaddingException {
        Cipher cipher = Cipher.getInstance(algorithmName, BouncyCastleProvider.PROVIDER_NAME);
        Key sm4Key = new SecretKeySpec(key, ALGORITHM_NAME);
        IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
        cipher.init(mode, sm4Key, ivParameterSpec);
        return cipher;
    }

    /**
     * 用CBC模式和PKCS5Padding填充的方式 进行加密
     *
     * @param key  秘钥
     * @param iv   偏移量(自定义的字符串)
     * @param data 加密前的数据
     * @return 加密后的数据
     * @throws InvalidKeyException       异常
     * @throws NoSuchAlgorithmException  异常
     * @throws NoSuchProviderException   异常
     * @throws NoSuchPaddingException    异常
     * @throws IllegalBlockSizeException 异常
     * @throws BadPaddingException       异常
     */
    private static byte[] encryptCbcPadding(byte[] key, byte[] iv, byte[] data)
            throws InvalidKeyException, NoSuchAlgorithmException, NoSuchProviderException,
            NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException,
            InvalidAlgorithmParameterException {
        Cipher cipher = generateCbcCipher(ALGORITHM_NAME_CBC_PADDING, Cipher.ENCRYPT_MODE, key, iv);
        return cipher.doFinal(data);
    }

    /**
     * 用CBC模式和PKCS5Padding填充的方式 进行解密
     *
     * @param key        秘钥
     * @param iv         偏移量(自定义的字符串)
     * @param cipherText 解密前的数据
     * @return 解密后的数据
     * @throws InvalidKeyException       异常
     * @throws NoSuchAlgorithmException  异常
     * @throws NoSuchProviderException   异常
     * @throws NoSuchPaddingException    异常
     * @throws IllegalBlockSizeException 异常
     * @throws BadPaddingException       异常
     */
    private static byte[] decryptCbcPadding(byte[] key, byte[] iv, byte[] cipherText)
            throws IllegalBlockSizeException, BadPaddingException, InvalidKeyException,
            NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException,
            InvalidAlgorithmParameterException {
        Cipher cipher = generateCbcCipher(ALGORITHM_NAME_CBC_PADDING, Cipher.DECRYPT_MODE, key, iv);
        return cipher.doFinal(cipherText);
    }

    /**
     * 用CBC模式和不填充的方式 进行加密
     *
     * @param key  秘钥
     * @param iv   偏移量(自定义的字符串)
     * @param data 加密前的数据
     * @return 加密后的数据
     * @throws InvalidKeyException       异常
     * @throws NoSuchAlgorithmException  异常
     * @throws NoSuchProviderException   异常
     * @throws NoSuchPaddingException    异常
     * @throws IllegalBlockSizeException 异常
     * @throws BadPaddingException       异常
     */
    private static byte[] encryptCbcNoPadding(byte[] key, byte[] iv, byte[] data)
            throws InvalidKeyException, NoSuchAlgorithmException, NoSuchProviderException,
            NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException,
            InvalidAlgorithmParameterException {
        Cipher cipher = generateCbcCipher(ALGORITHM_NAME_CBC_NOPADDING, Cipher.ENCRYPT_MODE, key, iv);
        return cipher.doFinal(data);
    }

    /**
     * 用ECB模式和不填充的方式 进行解密
     *
     * @param key        秘钥
     * @param iv         偏移量(自定义的字符串)
     * @param cipherText 加密后的数据
     * @return 解密后的数据
     * @throws InvalidKeyException       异常
     * @throws NoSuchAlgorithmException  异常
     * @throws NoSuchProviderException   异常
     * @throws NoSuchPaddingException    异常
     * @throws IllegalBlockSizeException 异常
     * @throws BadPaddingException       异常
     */
    private static byte[] decryptCbcNoPadding(byte[] key, byte[] iv, byte[] cipherText)
            throws IllegalBlockSizeException, BadPaddingException, InvalidKeyException,
            NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException,
            InvalidAlgorithmParameterException {
        Cipher cipher = generateCbcCipher(ALGORITHM_NAME_CBC_NOPADDING, Cipher.DECRYPT_MODE, key, iv);
        return cipher.doFinal(cipherText);
    }

    /**
     * 生成key并且转换为16进制字符串
     *
     * @return key
     * @throws NoSuchProviderException  异常
     * @throws NoSuchAlgorithmException 异常
     */
    public static String generateKey_Hex() throws Exception {
        return HexUtils.toHexString(generateKey());
    }

    /**
     * 用CBC模式和PKCS5Padding填充的方式 进行加密
     *
     * @param key  秘钥
     * @param iv   偏移量(自定义的字符串)
     * @param data 加密数据
     * @return 加密后的转换成Hex的数据
     */
    public static String encryptCbcPaddingHex(String key, String iv, String data) throws Exception {

        String iv_hex = HexUtils.toHexString(iv.getBytes());

        return HexUtils.toHexString(encryptCbcPadding(HexUtils.fromHexString(key),
                HexUtils.fromHexString(iv_hex), data.getBytes()));
    }

    /**
     * 用CBC模式和PKCS5Padding填充的方式 进行解密
     *
     * @param key        秘钥
     * @param iv         偏移量(自定义的字符串)
     * @param cipherText 待解密数据
     * @return 解密后的数据
     */
    public static String decryptCbcPaddingHex(String key, String iv, String cipherText) throws Exception {
        return new String(decryptCbcPadding(HexUtils.fromHexString(key), iv.getBytes(),
                HexUtils.fromHexString(cipherText)));
    }

    public static void main(String[] args) throws Exception {
        String data = "{\"test\":\"湖北利川深圳\"}";
        String iv = "blade12345678910";
//        String hexKey = generateKey_Hex();
        String hexKey = "20785fae41a54c65ab95d2db1abc7f9f";
        System.out.println("hexKey===" + hexKey);
        String cipher = encryptCbcPaddingHex(hexKey, iv, data);
        System.out.println("cipher==" + cipher);
        String b = decryptCbcPaddingHex(hexKey, iv, cipher);
        System.out.println(b);
    }
}

4:Android SM4 工具类,要把 

BouncyCastleProvider.PROVIDER_NAME 贴换为 new BouncyCastleProvider()  不然报错

5:

分别在拦截器里面调用 加解密方法。hexKey 可以自己生成。iv 自己定义16位

    String hexKey = "20785fae41a54c65ab95d2db1abc7f9f";
    String iv = "blade12345678910";

加密方法:

String encryptJson = Sm4Util.encryptCbcPaddingHex(hexKey, iv, String.valueOf(json));

解密方法:

 String decryptJson = Sm4Util.decryptCbcPaddingHex(hexKey, iv, String.valueOf(data));

6:这里面就不展示拦截器里面的代码。

7:截图展示加解密后的效果。

sm4在线解密,java,开发语言

 文章来源地址https://www.toymoban.com/news/detail-536582.html

到了这里,关于Android 数据SM4传输加解密的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 国密SM4对称加密Java加解密

    提示:国密SM4对称加密Java加解密 国家密码管理局 参考博文 SM4.0(原名SMS4.0)是中华人民共和国政府采用的一种分组密码标准,由国家密码管理局于2012年3月21日发布。相关标准为“GM/T 0002-2012《SM4分组密码算法》(原SMS4分组密码算法)”。 SM4 代码如下(示例): 在密码学中

    2024年02月11日
    浏览(18)
  • 国密算法 SM4 加解密 java 工具类

    👑 博主简介:知名开发工程师 👣 出没地点:北京 💊 2023年目标:成为一个大佬 ——————————————————————————————————————————— 版权声明:本文为原创文章,如需转载须注明出处,喜欢可收藏! 我国国家密码管理局陆续发

    2024年02月11日
    浏览(15)
  • java运用SM4国密算法对文件的加密与解密的实现

    首先我们在idae开发工具导入导入pom.xml的两个必要依赖  jar包下载地址:百度网盘 请输入提取码   npn8  图上systemPath 为jar包的文件路径,我们需要使用以下的路径存储jar包。(也可以自己设置) java包的文件路径如图所示 然后创建所需要加密的文件 ,需要加密的文件内容,

    2024年03月27日
    浏览(22)
  • 保护数据隐私:深入探索Golang中的SM4加密解密算法

    最近做的项目对安全性要求比较高,特别强调: 系统不能涉及MD5、SHA1、RSA1024、DES高风险算法。 那用什么嘞?甲方: 建议用国产密码算法SM4。 擅长敏捷开发(CV大法)的我,先去GitHub找了开源项目、又去网络上找了一些教程,但是或多或少都有些问题: 比如 golang.org/x/cryp

    2024年02月10日
    浏览(46)
  • 前端SM4加密解密

    前后端加密一致,如果不一致就是key有问题 调用方法: sm4.js文件

    2024年04月25日
    浏览(23)
  • SM4算法加解密及实现

    SM4.0(原名SMS4.0)是中华人民共和国政府采用的一种分组密码标准,由国家密码管理局于2012年3月21日发布。相关标准为“GM/T 0002-2012《SM4分组密码算法》(原SMS4分组密码算法)”。 在商用密码体系中,SM4主要用于数据加密,其算法公开,分组长度与密钥长度均为128bit,加密算

    2024年02月08日
    浏览(21)
  • 国密算法SM2/3/4简单比较,以及基于Java的SM4(ECB模式,CBC模式)对称加解密实现

    常用的国密算法包含SM2,SM3,SM4。以下针对每个算法使用场景进行说明以比较其差异 SM2:非对称加密算法,可以替代RSA 数字签名,SM2为非对称加密,加解密使用一对私钥和公钥,只有签名发行者拥有私钥,可用于加密,其他需要验证解密或验签者使用公钥进行。如果使用公

    2024年04月13日
    浏览(18)
  • js sm4实现加密解密

    2023.10.25今天我学习了如何使用sm4进行加密解密: 注意:前端和后端的编码必须相同才能使用,不然会出现空字符串的错误。 一、首先安装sm4.js包: package.json中的版本: (安装失败的话可以直接复制下面的版本然后npm install) 二、main.js中全局引入或局部引入: 这个是全局

    2024年01月18日
    浏览(22)
  • 前端使用国密sm2和sm4进行加解密

    国密SM:国密算法,即国家商用密码算法。是由国家密码管理局认定和公布的密码算法标准及其应用规范,其中部分密码算法已经成为国际标准。如SM系列密码,SM代表商密,即商业密码,是指用于商业的、不涉及国家秘密的密码技术。 安装SM加密依赖 SM2 封装 将sm2的加密解密

    2024年02月08日
    浏览(28)
  • 基于hutool 封装国密sm2,sm4 加解密算法

    基于hutool 封装国密sm2,sm4 加解密算法 1. 加入依赖包 2. 编码

    2024年02月13日
    浏览(20)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包