Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hutool SmUtil 中对SM4算法的实现 对GraalVM不友好 #2825

Closed
wssy001 opened this issue Dec 23, 2022 · 6 comments
Closed

Hutool SmUtil 中对SM4算法的实现 对GraalVM不友好 #2825

wssy001 opened this issue Dec 23, 2022 · 6 comments
Labels

Comments

@wssy001
Copy link

wssy001 commented Dec 23, 2022

版本情况

JDK版本: GraalVM CE 22.3.0 with Open JDK 19.0.1
hutool版本: 5.8.10

问题描述(包括截图)

当用户需要使用SM4算法并用GraalVM编译后会提示 BC Provider未注册,但其实BC Provider已成功注册,因为由SmUtil封装的SM2,SM3算法均可正常使用。
image

  1. 复现代码
SM4 sm4 = SmUtil.sm4();
String encryptHex = sm4.encryptHex("Hello World");
log.info("******TestController.test:encryptHex:{}", encryptHex);
String decryptStr = sm4.decryptStr(encryptHex);
log.info("******TestController.test:decryptStr:{}", decryptStr);

原谅鄙人没有能力进行PR,改进参考:

static class Sm4Util {
        private static final String ALGORITHM_NAME = "SM4";
        private static final String ALGORITHM_ECB_PKCS5PADDING = "SM4/ECB/PKCS5Padding";
        /**
         * SM4算法目前只支持128位(即密钥16字节)
         */
        private static final int DEFAULT_KEY_SIZE = 128;


        /**
         * 生成密钥
         * <p>建议使用DigestUtil.binToHex将二进制转成HEX</p>
         *
         * @return 密钥16位
         * @throws Exception 生成密钥异常
         */
        public static byte[] generateKey() throws Exception {
            checkBouncyCastleProvider();
            KeyGenerator kg = KeyGenerator.getInstance(ALGORITHM_NAME, BouncyCastleProvider.PROVIDER_NAME);
            kg.init(DEFAULT_KEY_SIZE, new SecureRandom());
            return kg.generateKey().getEncoded();
        }

        /**
         * 加密,SM4-ECB-PKCS5Padding
         *
         * @param data 要加密的明文
         * @param key  密钥16字节,使用Sm4Util.generateKey()生成
         * @return 加密后的密文
         * @throws Exception 加密异常
         */
        public static byte[] encrypt(byte[] data, byte[] key) throws Exception {
            return sm4(data, key, Cipher.ENCRYPT_MODE);
        }

        /**
         * 解密,SM4-ECB-PKCS5Padding
         *
         * @param data 要解密的密文
         * @param key  密钥16字节,使用Sm4Util.generateKey()生成
         * @return 解密后的明文
         * @throws Exception 解密异常
         */
        public static byte[] decrypt(byte[] data, byte[] key) throws Exception {
            return sm4(data, key, Cipher.DECRYPT_MODE);
        }

        /**
         * SM4对称加解密
         *
         * @param input 明文(加密模式)或密文(解密模式)
         * @param key   密钥
         * @param mode  Cipher.ENCRYPT_MODE - 加密;Cipher.DECRYPT_MODE - 解密
         * @return 密文(加密模式)或明文(解密模式)
         * @throws Exception 加解密异常
         */
        private static byte[] sm4(byte[] input, byte[] key, int mode)
                throws Exception {
            checkBouncyCastleProvider();

            SecretKeySpec sm4Key = new SecretKeySpec(key, ALGORITHM_NAME);
            Cipher cipher = Cipher
                    .getInstance(ALGORITHM_ECB_PKCS5PADDING, BouncyCastleProvider.PROVIDER_NAME);
            cipher.init(mode, sm4Key);
            return cipher.doFinal(input);
        }

        private static void checkBouncyCastleProvider() {
            if (null == Security.getProvider(BouncyCastleProvider.PROVIDER_NAME)) {
                Security.addProvider(new BouncyCastleProvider());
            }
        }
    }

该Util内容源自于网上,此issue旨在为那些有需要在GraalVM上使用SM4的朋友少走一点弯路。

@changhr2013
Copy link
Contributor

我其实在想,要不要重构 smutil,一了百了,越过 jce,直接调用 bc 库的算法引擎类实现一版国密算法工具类🤔这样所有由 jce provider 引发的问题就都解决掉了。

@CherryRum
Copy link
Collaborator

没想象的那么简单,毕竟bc库还是要注入Provider

@changhr2013
Copy link
Contributor

仅仅国密系列这几个算法实现的话,应该是可以完全绕过 JCE 的,核心就是几个纯算法 Engine 类,不需要外部依赖,就是写起来可能稍微繁琐些,我回头有时间整理一下试试看

@CherryRum
Copy link
Collaborator

你可以试试,我当初尝试过,不太行

@changhr2013
Copy link
Contributor

哈哈哈,初步验证成功了
graal-vm-sm4

@looly
Copy link
Member

looly commented Dec 27, 2022

其实Hutool的所有算法都是依赖于JCE的,这个暂时无解。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants