开启辅助访问 切换到宽版

精易论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

用微信号发送消息登录论坛

新人指南 邀请好友注册 - 我关注人的新帖 教你赚取精币 - 每日签到


求职/招聘- 论坛接单- 开发者大厅

论坛版规 总版规 - 建议/投诉 - 应聘版主 - 精华帖总集 积分说明 - 禁言标准 - 有奖举报

查看: 295|回复: 8
收起左侧

[精币悬赏] 求大神按我发的Java的例子改写成E语言的 是关于SM4加解密的

[复制链接]
结帖率:0% (0/2)
发表于 2024-8-17 17:51:57 | 显示全部楼层 |阅读模式   河北省唐山市
500精币


import org.bouncycastle.jce.provider.BouncyCastleProvider;
import sun.misc.BASE64Decoder;


import javax.crypto.*;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.util.Arrays;
import java.util.Base64;


public class TestEncrypt {




    static {
        try {
            Security.addProvider(new BouncyCastleProvider());
        } catch (Exception e) {
        }
    }




    /**
     * 秘钥空间大小.
     */
    public static final int SM4_KEY_SIZE = 128;


    /**
     * 默认秘钥空间为128,Key的长度是16.
     */
    public static final int SM4_KEY_LENGTH = 16;


    /**
     * 算法编号.
     */
    public static final String SM4_NAME = "SM4";


    /**
     * CBC模式串.
     */
    public static final String SM4_NAME_ECB = "SM4/CBC/PKCS5Padding";


    /**
     * 首次加密初始向量.
     */
    protected static final byte[] SM4_KEY_IV = {1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31};


    /**
     * 生成SM4算法的KEY.
     *
     * @Return 生成的SM4秘钥.
     * @throws Exception .
     */
    public String generateSm4Key() {
        try {
            return Base64.getEncoder().encodeToString(generateSm4Key(SM4_KEY_SIZE));
        } catch (NoSuchAlgorithmException | NoSuchProviderException e) {
        }
        return null;
    }


    /**
     * 生成SM4算法的KEY.
     *
     * @param sm4Key 指定秘钥空间大小.
     * @return 生成的SM4秘钥.
     * @throws Exception .
     */
    private static byte[] generateSm4Key(int sm4Key) throws NoSuchAlgorithmException, NoSuchProviderException {


        KeyGenerator keyGenerator = KeyGenerator.getInstance(SM4_NAME, BouncyCastleProvider.PROVIDER_NAME);
        keyGenerator.init(sm4Key, new SecureRandom());
        return keyGenerator.generateKey().getEncoded();
    }


    /**
     * 对文本内容进行加密.
     *
     * @param plainText 待加密明文内容.
     * @param sm4Key    SM4秘钥.
     * @return 加密的密文.
     */
    public String encodeText(String plainText, String sm4Key) {
        try {
            return encodeByCbc(plainText, sm4Key);
        } catch (NoSuchProviderException | BadPaddingException | NoSuchAlgorithmException | IllegalBlockSizeException | NoSuchPaddingException e) {
        }
        return null;
    }


    /**
     * 对文本密文进行解密.
     *
     * @param cipherText 待解密密文.
     * @param sm4Key     SM4秘钥.
     * @return 解密的明文.
     * @throws Exception .
     */
    public String decodeText(String cipherText, String sm4Key) {
        return decodeByCbc(cipherText, sm4Key);
    }


    /**
     * 对字节数组内容进行加密.
     *
     * @param sm4Key SM4秘钥.
     * @return 加密的密文.
     */
    public byte[] encodeBytes(byte[] plainBytes, String sm4Key) {
        byte[] sm4KeyBytes = null;
        byte[] cipherBytes = null;


        try {
            // 秘钥位数处理转换.
            sm4Key = sm4KeyPadding(sm4Key);
            // base64格式秘钥转换:sm4Key to byte[].
            sm4KeyBytes = Base64.getDecoder().decode(sm4Key);
            // 使用转换后的原文和秘钥进行加密操作.
            cipherBytes = encodeCbcPadding(plainBytes, sm4KeyBytes);
            // 对加密结果使用base64进行编码:cipherBytes to Base64格式.
        } catch (Exception ex) {
            cipherBytes = new byte[]{1};
        }
        return cipherBytes;
    }


    /**
     * 对字节数组密文进行解密.
     *
     * @param sm4Key SM4秘钥.
     * @return 解密的明文.
     */
    public byte[] decodeBytes(byte[] cipherBytes, String sm4Key) {
        byte[] keyBts = null;
        byte[] plainBytes = new byte[0];


        try {
            // 秘钥位数处理转换.
            sm4Key = sm4KeyPadding(sm4Key);
            // base64格式秘钥转换:sm4Key to byte[].
            keyBts = Base64.getDecoder().decode(sm4Key);
            // 使用转换后的密文和秘钥进行解密操作
            plainBytes = decryptCbcPadding(cipherBytes, keyBts);
        } catch (Exception ex) {
            plainBytes = new byte[]{0};
        }
        return plainBytes;
    }


    /**
     * 基于CBC模式进行SM4加密.
     *
     * @param plainText 待加密明文.
     * @param sm4Key    Base64格式秘钥.
     * @return 加密后Base64格式密文.
     * @throws Exception 可能异常.
     */
    private String encodeByCbc(String plainText, String sm4Key) throws NoSuchProviderException, BadPaddingException, NoSuchAlgorithmException, IllegalBlockSizeException, NoSuchPaddingException {
        String cipherText = "";
        byte[] sm4KeyBytes = null;
        byte[] plainBytes = null;
        byte[] cipherBytes = null;


        try {
            // 秘钥位数处理转换.
            sm4Key = sm4KeyPadding(sm4Key);
            // base64格式秘钥转换:sm4Key to byte[].
            sm4KeyBytes = Base64.getDecoder().decode(sm4Key);
            // String格式原文转换:plainText to byte[].
            plainBytes = plainText.getBytes(StandardCharsets.UTF_8);
            // 使用转换后的原文和秘钥进行加密操作.
            cipherBytes = encodeCbcPadding(plainBytes, sm4KeyBytes);
            // 对加密结果使用base64进行编码:cipherBytes to Base64格式.
            cipherText = Base64.getEncoder().encodeToString(cipherBytes);
        } catch (RuntimeException ex) {
            cipherText = "";
        }
        return cipherText;
    }


    /**
     * SM4算法的CBC模式加密.
     *
     * @param plainBytes 待加密明文.
     * @param sm4Key     Base64格式秘钥.
     * @return 加密后byte[]格式密文.
     * @throws Exception 可能异常.
     */
    private byte[] encodeCbcPadding(byte[] plainBytes, byte[] sm4Key) throws NoSuchPaddingException, NoSuchAlgorithmException, NoSuchProviderException, BadPaddingException, IllegalBlockSizeException {
        Cipher cipher = generateSm4EcbCipher(SM4_NAME_ECB, Cipher.ENCRYPT_MODE, sm4Key);
        return cipher.doFinal(plainBytes);
    }


    /**
     * 基于CBC模式进行SM4解密.
     *
     * @param cipherText 待解密密文.
     * @param sm4Key     Base64格式秘钥.
     * @return 解密后原文.
     * @throws Exception 可能异常.
     */
    private String decodeByCbc(String cipherText, String sm4Key) {
        String plainText = "";
        byte[] keyBts = null;
        byte[] cipherBts = null;
        byte[] plainBytes = null;




        // 使用转换后的密文和秘钥进行解密操作
        try {
            // 秘钥位数处理转换.
            sm4Key = sm4KeyPadding(sm4Key);
            // base64格式秘钥转换:sm4Key to byte[].
            BASE64Decoder decoder = new BASE64Decoder();
            //sm4KeyBytes = Base64.getDecoder().decode(sm4Key.getBytes(StandardCharsets.UTF_8));
            keyBts = decoder.decodeBuffer(sm4Key);
            //keyBts = Base64.getDecoder().decode(sm4Key);
            // base64格式密文转换:cipherText to byte[].
            cipherBts = decoder.decodeBuffer(cipherText);
            plainBytes = decryptCbcPadding(cipherBts, keyBts);
        } catch (NoSuchAlgorithmException | NoSuchProviderException | NoSuchPaddingException | BadPaddingException | IllegalBlockSizeException | IOException e) {
            e.printStackTrace();
        }
        // 将解密结果转换为字符串:srcData to String.
        plainText = new String(plainBytes, StandardCharsets.UTF_8);
        return plainText;
    }




    /**
     * SM4算法的CBC模式解密.
     *
     * @param sm4Key Base64格式秘钥.
     * @return 解密后byte[]格式密文.
     * @throws Exception 可能异常.
     */
    private byte[] decryptCbcPadding(byte[] cipherBytes, byte[] sm4Key) throws NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException, BadPaddingException, IllegalBlockSizeException {




        Cipher cipher = generateSm4EcbCipher(SM4_NAME_ECB, Cipher.DECRYPT_MODE, sm4Key);
        return cipher.doFinal(cipherBytes);
    }


    /**
     * 针对错误的秘钥进行补齐或除余操作.
     *
     * @param sm4Key Base64格式秘钥.
     * @return 补齐或除余后的结果.
     */
    private static String sm4KeyPadding(String sm4Key) {
        String targetSm4Key = null;
        byte[] sm4KeyBytes = null;
        byte[] targetSm4KeyBts = null;


        try {
            if (null == sm4Key) {
                targetSm4Key = "";
                return targetSm4Key;
            }
            BASE64Decoder decoder = new BASE64Decoder();
            //sm4KeyBytes = Base64.getDecoder().decode(sm4Key.getBytes(StandardCharsets.UTF_8));
            sm4KeyBytes = decoder.decodeBuffer(sm4Key);
            //System.out.println(new String(decoder.decodeBuffer(sm4Key), "UTF-8"));
            // 若Key超长,则除去多余的内容.
            if (sm4KeyBytes.length > SM4_KEY_LENGTH) {
                targetSm4KeyBts = new byte[SM4_KEY_LENGTH];
                System.arraycopy(sm4KeyBytes, 0, targetSm4KeyBts, 0, SM4_KEY_LENGTH);


            }
            // 若Key较短,则补齐多余的内容.
            else if (sm4KeyBytes.length < SM4_KEY_LENGTH) {
                targetSm4KeyBts = new byte[SM4_KEY_LENGTH];
                System.arraycopy(sm4KeyBytes, 0, targetSm4KeyBts, 0, sm4KeyBytes.length);
                Arrays.fill(targetSm4KeyBts, sm4KeyBytes.length, SM4_KEY_LENGTH, (byte) 1);
            } else {
                targetSm4KeyBts = sm4KeyBytes;
            }
        } catch (Exception ex) {
            ex.printStackTrace();
//            log.error("SM4Util.sm4KeyPadding.", ex);
            targetSm4KeyBts = new byte[0];
        }
        // 以Base64格式返回Key.
        return Base64.getEncoder().encodeToString(targetSm4KeyBts);
    }


    /**
     * 生成SM4算法实例.
     *
     * @param sm4Name 算法名称.
     * @param sm4Mode 加密模式.
     * @param sm4Key  秘钥内容.
     * @return SM4算法实例.
     * @throws Exception 可能异常.
     */
    private Cipher generateSm4EcbCipher(String sm4Name, int sm4Mode, byte[] sm4Key) throws NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException {




        Cipher cipher = Cipher.getInstance(sm4Name, BouncyCastleProvider.PROVIDER_NAME);
        Key secretKey = new SecretKeySpec(sm4Key, SM4_NAME);
        IvParameterSpec ivParameterSpec = new IvParameterSpec(SM4_KEY_IV);
        try {
            cipher.init(sm4Mode, secretKey, ivParameterSpec);
        } catch (InvalidKeyException | InvalidAlgorithmParameterException e) {
            e.printStackTrace();
        }
        return cipher;
    }


    public static void main(String[] args) {
        String data = "{\n" +
                "    \"entId\": \"0b094b92804a4a3aa6f611b863f4080f\",\n" +
                "    \"wasteId\": \"34a9849ce7d14358915325f94bd0c61c\",\n" +
                "    \"quantity\": 0.003 ,\n" +
                "    \"unit\": \"吨\",\n" +
                "    \"sourceId\": \"a238ef2e6f744944ba1ab9a69bbcadd5\",\n" +
                "    \"produceDate\": \"2021-07-01 01:02:02\",\n" +
                "    \"userName\": \"测试用户0714\",\n" +
                "    \"iotToken\": \"a238ef2e6f744944ba1ab9a69bbcadd5\",\n" +
                "    \"remark\": \"测试数据\"\n" +
                "  }";
        String key = "903B2CBD-D669-47E3-A6D9-94655C72B3BB";
        TestEncrypt encrypt = new TestEncrypt();
        String encryptData = encrypt.encodeText(data, key);
        System.out.println("encryptData(拷贝到请求体中):" + encryptData);
        String plainText = encrypt.decodeText(encryptData, key);
        System.out.println("plainText:" + plainText);
    }


}


数据加密传输.zip

2.81 MB, 下载次数: 3, 下载积分: 精币 -1 枚

java

签到天数: 23 天

发表于 2024-8-17 19:42:39 | 显示全部楼层   广东省广州市
回复

使用道具 举报

结帖率:0% (0/2)
 楼主| 发表于 2024-8-17 19:44:42 | 显示全部楼层   河北省唐山市
baitso 发表于 2024-8-17 19:42
https://bbs.125.la/forum.php?mod=viewthread&tid=14330740
看看合不合适用

这个我用不来,您能给改下吗
回复

使用道具 举报

签到天数: 23 天

发表于 2024-8-17 20:06:48 | 显示全部楼层   广东省广州市
不知道是不是你想要的结果了
sm4.e (47.28 KB, 下载次数: 7)

点评

散了吧 他自己都不知道正确结果是什么 虽然代码里写的最后是BASE64 但他也说验证都没办法~   广东省揭阳市  详情 回复 发表于 2024-8-17 22:51
回复

使用道具 举报

结帖率:60% (15/25)

签到天数: 21 天

发表于 2024-8-17 20:15:13 | 显示全部楼层   江苏省苏州市
我这里有,要收费的
回复

使用道具 举报

结帖率:0% (0/2)
 楼主| 发表于 2024-8-17 20:33:31 | 显示全部楼层   河北省唐山市
baitso 发表于 2024-8-17 20:06
不知道是不是你想要的结果了

他那个用BASE64编码了
回复

使用道具 举报

签到天数: 22 天

发表于 2024-8-17 22:51:11 | 显示全部楼层   广东省揭阳市
baitso 发表于 2024-8-17 20:06
不知道是不是你想要的结果了

散了吧 他自己都不知道正确结果是什么 虽然代码里写的最后是BASE64 但他也说验证都没办法~




回复

使用道具 举报

签到天数: 23 天

发表于 2024-8-17 22:59:37 | 显示全部楼层   广东省广州市
Hoibben 发表于 2024-8-17 22:51
散了吧 他自己都不知道正确结果是什么 虽然代码里写的最后是BASE64 但他也说验证都没办法~

嗯,我也觉得是!无非就是java一端加密,易语言验证!base64 自己加解下就可以得出结果对不对了
回复

使用道具 举报

结帖率:0% (0/2)
 楼主| 发表于 2024-8-17 23:24:11 | 显示全部楼层   河北省唐山市
Hoibben 发表于 2024-8-17 22:51
散了吧 他自己都不知道正确结果是什么 虽然代码里写的最后是BASE64 但他也说验证都没办法~

大神,您不帮忙就算了,但您不能打消别人的积极性
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则 致发广告者

发布主题 收藏帖子 返回列表

sitemap| 易语言源码| 易语言教程| 易语言论坛| 易语言模块| 手机版| 广告投放| 精易论坛
拒绝任何人以任何形式在本论坛发表与中华人民共和国法律相抵触的言论,本站内容均为会员发表,并不代表精易立场!
论坛帖子内容仅用于技术交流学习和研究的目的,严禁用于非法目的,否则造成一切后果自负!如帖子内容侵害到你的权益,请联系我们!
防范网络诈骗,远离网络犯罪 违法和不良信息举报电话0663-3422125,QQ: 793400750,邮箱:wp@125.la
Powered by Discuz! X3.4 揭阳市揭东区精易科技有限公司 ( 粤ICP备12094385号-1) 粤公网安备 44522102000125 增值电信业务经营许可证 粤B2-20192173

快速回复 返回顶部 返回列表