Hyperledger-TWGC/java-gm

资源泄漏的问题比较多

linenlin01 opened this issue · 11 comments

例如:

    public static PublicKey loadPublicFromFile(String filename) throws IOException, NoSuchProviderException, NoSuchAlgorithmException, InvalidKeySpecException {
        FileReader fr = new FileReader(filename);
        PemObject spki = new PemReader(fr).readPemObject();
        fr.close();
        Provider p = Security.getProvider(BouncyCastleProvider.PROVIDER_NAME);
        return KeyFactory.getInstance(Const.EC_VALUE, BouncyCastleProvider.PROVIDER_NAME).generatePublic(new X509EncodedKeySpec(spki.getContent()));
    }

Description Resource Path Location Type Resource leak: '' is never closed SM2Util.java /java-gm/src/main/java/twgc/gm/sm2 line 241 Java Problem

  1. SM2的密钥基于证书文件,没有提供基于hash to Byte 的转化方法,因此和JS(sm-crypto)的互操作比较困的

@linenlin01 感谢您的反馈!想知道下提及的sm-crypto库是哪一个?方便提供链接么?

@davidkhala 应该说的是这个JavaScript 库 sm-crypto

希望大家帮忙做几个事情

  1. 将泄漏检测机制添加到java-gm的ci中,使得该问题得以浮现。https://github.com/Hyperledger-TWGC/java-gm/blob/master/src/main/java/twgc/gm/sm2/SM2Util.java 这个文件一共240行,报错在241行?
  2. 如果可以提交pr修复问题
  3. 请问hash to byte的转化方法是必须的么?有关hash to byte的背景原因是什么?

@linenlin01 能邀请sm-crypto的作者来参与讨论么?

在SM2和Jsm-crypto 的互操作上可以参考gmhelper的实现
https://github.com/ZZMarquis/gmhelper

下列的代码是另外写的测试

	@Test
	public void testDecryptWithSmCrypto() throws Exception {
		String encryptedData = "d2dbc0db9212e0fcae2b9617b781042a737f92ad083e4452ebe1cf6b5ac687819fabe55d46d7260e99f08696500762eddcb51a2d984c63ef79262c898b82f8b48ab353960a9a5121fa3da543dc7f0f2eee56fa2f03564408a95a59d27ef7f276f0185b6381c70ebd912f";
		// 密文需要加04后传入解密
		encryptedData = "04" + encryptedData;
		ECPrivateKeyParameters privatekey = BCECUtil.createECPrivateKeyParameters(
				"58967e2beb6fffd3c96545eebd3000b39c10087d48faa0d41f9c7bf3720e0ea4", SM2Util.DOMAIN_PARAMS);
		byte[] decryptedData = SM2Util.decrypt(Mode.C1C3C2, privatekey, Hex.decode(encryptedData));
		System.out.println("SM2 decryptWithSmCrypto result:\n" + new String(decryptedData));
	}

在SM2和Jsm-crypto 的互操作上可以参考gmhelper的实现 https://github.com/ZZMarquis/gmhelper

下列的代码是另外写的测试

	@Test
	public void testDecryptWithSmCrypto() throws Exception {
		String encryptedData = "d2dbc0db9212e0fcae2b9617b781042a737f92ad083e4452ebe1cf6b5ac687819fabe55d46d7260e99f08696500762eddcb51a2d984c63ef79262c898b82f8b48ab353960a9a5121fa3da543dc7f0f2eee56fa2f03564408a95a59d27ef7f276f0185b6381c70ebd912f";
		// 密文需要加04后传入解密
		encryptedData = "04" + encryptedData;
		ECPrivateKeyParameters privatekey = BCECUtil.createECPrivateKeyParameters(
				"58967e2beb6fffd3c96545eebd3000b39c10087d48faa0d41f9c7bf3720e0ea4", SM2Util.DOMAIN_PARAMS);
		byte[] decryptedData = SM2Util.decrypt(Mode.C1C3C2, privatekey, Hex.decode(encryptedData));
		System.out.println("SM2 decryptWithSmCrypto result:\n" + new String(decryptedData));
	}

关于互操作,这里是TWGC的互操作验证方式。https://github.com/Hyperledger-TWGC/GM-interoperability
https://github.com/ZZMarquis/gmhelper 库中,好像并没有看到对应js库的调用方式?

鉴于两个库 都有 SM2Util 这个类,请问您这边确定没提交错问题?
底层两个库都是基于

implementation group: 'org.bouncycastle', name: 'bcpkix-jdk15on', version: '1.67'

我理解差距应该不大。

另外写的测试怎么了么?

另外写的测试是sm-crypto加密的结果,用 https://github.com/ZZMarquis/gmhelper 来解密

另外写的测试是sm-crypto加密的结果,用 https://github.com/ZZMarquis/gmhelper 来解密

@linenlin01 或者 @changhr2013 几个事情麻烦回答一下。

  1. 将泄漏检测机制添加到java-gm的ci中,使得该问题得以浮现。https://github.com/Hyperledger-TWGC/java-gm/blob/master/src/main/java/twgc/gm/sm2/SM2Util.java 这个文件一共240行,报错在241行?
  2. 如果可以提交pr修复问题
  3. 请问hash to byte的转化方法是必须的么?有关hash to byte的背景原因是什么?
  4. 能邀请sm-crypto的作者来参与讨论么?

我个人的一些观点和考虑:

  • 如果文件只有240行,报错在241行,无法复现或者定位的话,无助于我们进行修复。
  • 如果hash to byte不是必须的,或者规范方法,则不考虑实现某特定库的方法。
  • 如果无法复现或者改进的话,则会作为问题关闭这个issue

cc: @davidkhala

我只是个路过的,大概讲一下吧:

  1. Java 操作 IO 流是需要确保关闭的,因此一般会在 finally 语句块中关闭资源,或者直接使用 try-with-resources 语法,对应的应该就是楼上说的资源泄露问题。
  2. hash to byte 说法应该有误,我猜应该是指的 Hex 编解码的方法,以及 Java 公私钥对象和 SM2 裸公私钥字节数组的转换方法,Hex 编解码 BC 库有提供,可以忽略。(因为 sm-crypto 库的输入输出都是使用 Hex 编码的,SM2 的公私钥也是裸公私钥的形式)

最后,关于国密的算法库封装,其实我感觉用 hutool-crypto 就够用了啊。

我只是个路过的,大概讲一下吧:

  1. Java 操作 IO 流是需要确保关闭的,因此一般会在 finally 语句块中关闭资源,或者直接使用 try-with-resources 语法,对应的应该就是楼上说的资源泄露问题。
  2. hash to byte 说法应该有误,我猜应该是指的 Hex 编解码的方法,以及 Java 公私钥对象和 SM2 裸公私钥字节数组的转换方法,Hex 编解码 BC 库有提供,可以忽略。(因为 sm-crypto 库的输入输出都是使用 Hex 编码的,SM2 的公私钥也是裸公私钥的形式)

最后,关于国密的算法库封装,其实我感觉用 hutool-crypto 就够用了啊。

  1. 设计上是想把IO相关的操作依赖倒置给用户,如果实现上有问题,改就是了。因此从风格上我们把所有的exception都抛出了。
  2. https://github.com/Hyperledger-TWGC/tjfoc-gm/blob/dev-fabric/x509/utils.go#L25 参考这里,我理解目前TWGC下的国密库统一使用的格式可能不是hex