Git Product home page Git Product logo

java-gm's Introduction

java-gm

基于BouncyCastle实现国密算法SM2、SM3、SM4的操作类,并验证与其他语言(NodeJS、Go)实现的国密库的互操作性。

Build Status

Feature 功能支持列表

SM2功能 支持范围
Generate KeyPair
Derive public key from private key
Sign
Verify
PEM格式导出 私钥/公钥/CSR
PEM文件加密 RFC5958
PEM格式导入 私钥/公钥/CSR

备注:

C1C3C2和SM2SM3作为默认的加密和Hash算法,同时接口层面保留C1C2C3和其他Hash方式的支持。

SM4功能 支持范围
Generate Key
Encrypt, Decrypt
PEM格式导出
PEM文件加密
分组模式 ECB/CBC/CFB/OFB/CTR
SM3功能 支持范围
当前语言Hash接口兼容

ObjectPoolSupport

我们采用了可配置的对象池的方案来提供相对便利的多线程支持。 如:

    static SM2EnginePool sm2EnginePool = new SM2EnginePool(SM2Engine.Mode.C1C3C2);
    SM2Engine sm2Engine = sm2EnginePool.borrowObject();
    byte[] encrypted = instance.encrypt(sm2Engine, this.pubKey, message);
    byte[] rs = instance.decrypt(sm2Engine, this.privKey, encrypted);
    Assert.assertEquals(new String(message), new String(rs));
    sm2EnginePool.returnObject(sm2Engine);

具体对象池的配置参考如下文件: pool-config.yaml, 我们目前尚未使用统一的对象池,而是根据不同密码学算法使用不同的对象池。 这里是考虑到不同算法的执行效率并不相同,因此例如sm2+sm3的操作: 我们可以考虑用一个数量更小的sm3对象池,来对接一个sm2对象池,来实现摘要(SM3)签名(SM2)这一密码学实现。

Terminology 术语

  • SM2: 国密椭圆曲线算法库
  • SM3: 国密hash算法库
  • SM4: 国密分组密码算法库

How to Contribute 贡献须知

We welcome contributions to Hyperledger in many forms, and there's always plenty to do!

Please visit the contributors guide in the docs to learn how to make contributions to this exciting project.

Creative Commons License
This work is licensed under a Creative Commons Attribution 4.0 International License.

License 许可证

Hyperledger Project source code files are made available under the Apache License, Version 2.0 (Apache-2.0), located in the LICENSE file.

java-gm's People

Contributors

davidkhala avatar dependabot[bot] avatar photowey avatar ryjones avatar samyuan1990 avatar xiaohui249 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

java-gm's Issues

[提议] 支持通过直接读取公私钥字符串来加载其对象

提议描述:
通常有些场景是将公私钥配置在配置文件或者配置中心里面,这个时候我们的工具类似乎就有点力不从心,当然可以自己实现。

例子:
加载公钥:

twgc.gm.sm2.SM2Util#loadPublicFromFile

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

期望:

// 提供类似的方法可以通过读取字符串来加载
PemReader pemReader = new PemReader(new StringReader(publicKey))

资源泄漏的问题比较多

例如:

    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)的互操作比较困的

sm4 Enum

Cipher cipher = Cipher.getInstance(sm4ModeAndPaddingEnum.getName(), BouncyCastleProvider.PROVIDER_NAME);

我们可以吧cipher作为枚举值么? 这样就避免了每次都去getInstance了。

EnvelopeMessage Encryption failed

`
/**
* 加密数据
* @param srcMsg 源信息
* @param certPath 证书路径
* @param charSet 字符编码
* @return
* @throws Exception
*/
public String envelopeMessage(String srcMsg, String certPath, String charSet) throws Exception {
CertificateFactory certificatefactory;
X509Certificate cert;
// 使用公钥对对称密钥进行加密 //若此处不加参数 "BC" 会报异常:CertificateException -
certificatefactory = CertificateFactory.getInstance("X.509", "BC");
// 读取.crt文件;你可以读取绝对路径文件下的crt,返回一个InputStream(或其子类)即可。
InputStream bais = new FileInputStream(certPath);
cert = (X509Certificate) certificatefactory.generateCertificate(bais);
//添加数字信封
CMSTypedData msg = new CMSProcessableByteArray(srcMsg.getBytes(charSet));
CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator();
edGen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(
cert).setProvider("BC"));
CMSEnvelopedData ed = edGen.generate(msg,
new JceCMSContentEncryptorBuilder(PKCSObjectIdentifiers.RC2_CBC)
.setProvider("BC").build());
String rslt = new String(Base64.encode(ed.getEncoded()));
System.out.println(rslt);
return rslt;
}

public MessageUtil() {
Security.addProvider(new BouncyCastleProvider());
// Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
}

`
org.bouncycastle.cms.CMSException: exception wrapping content key: cannot create cipher: No such algorithm: 1.2.840.10045.2.1

at org.bouncycastle.cms.KeyTransRecipientInfoGenerator.generate(Unknown Source)
at org.bouncycastle.cms.CMSEnvelopedDataGenerator.doGenerate(Unknown Source)
at org.bouncycastle.cms.CMSEnvelopedDataGenerator.generate(Unknown Source)
at MessageUtil.envelopeMessage(MessageUtil.java:167)
at envelopeTest.generate(envelopeTest.java:8)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)

Caused by: org.bouncycastle.operator.OperatorCreationException: cannot create cipher: No such algorithm: 1.2.840.10045.2.1
at org.bouncycastle.operator.jcajce.OperatorHelper.createAsymmetricWrapper(Unknown Source)
at org.bouncycastle.operator.jcajce.JceAsymmetricKeyWrapper.generateWrappedKey(Unknown Source)
... 27 more
Caused by: java.security.NoSuchAlgorithmException: No such algorithm: 1.2.840.10045.2.1
at javax.crypto.Cipher.getInstance(Cipher.java:688)
at javax.crypto.Cipher.getInstance(Cipher.java:596)
at org.bouncycastle.jcajce.util.NamedJcaJceHelper.createCipher(Unknown Source)
... 29 more
`

The encryption certificate used is as follow:

-----BEGIN CERTIFICATE----- MIICmDCCAj6gAwIBAgIIICADCQACNmIwCgYIKoEcz1UBg3UwdjEcMBoGA1UEAwwTU21hcnRDQV9UZXN0X1NNMl9DQTEVMBMGA1UECwwMU21hcnRDQV9UZXN0MRAwDgYDVQQKDAdTbWFydENBMQ8wDQYDVQQHDAbljZfkuqwxDzANBgNVBAgMBuaxn+iLjzELMAkGA1UEBhMCQ04wHhcNMjAwMzA5MDgxNTI4WhcNMjEwMzA5MDgxNTI4WjCBrjEqMCgGA1UELQwhZmZlYjNlM2IxZWI3NDFlOGFjMDRhZDllZGU4ZDg3OGMxMQswCQYDVQQGEwJDTjESMBAGA1UECAwJ5rGf6IuP55yBMRIwEAYDVQQHDAnoi4/lt57luIIxDDAKBgNVBAoMAzAwMTESMBAGA1UECwwJ5Zu65a6a5YC8MSkwJwYDVQQDDCDoi4/lt57lkIzmtY7ljLrlnZfpk77noJTnqbbpmaJAMTBZMBMGByqGSM49AgEGCCqBHM9VAYItA0IABHaRmfiRODgUqYFFj514NrJbiC8i76U/Up9nlUYglm/EY48yk4rnaDqQbZ52EBatWuCSo7eJq1r8hNZVtZfyys+jfTB7MAsGA1UdDwQEAwIDODAMBgNVHRMEBTADAQH/MB0GA1UdDgQWBBS9yBor73EI3noVdS52WdLiFqG9HzAfBgNVHSMEGDAWgBRc87oljMJlDOxn777djWunXq/jrDAeBggqgRzQFAQBAwQSExAxMjM0NTY3ODkwUVdFUlRZMAoGCCqBHM9VAYN1A0gAMEUCIFlHt1MFenymSpEKzQgySo0F5TGEWhSGInvCHDq75bU9AiEAqLfCLkCvkNu1+8Vw3Fee3r3K9MvhsAMc61axwT5SEXs= -----END CERTIFICATE-----

add support/test sample for different hash function

1.2.156.10197.1.501 SM2Sign-with-SM3
1.2.156.10197.1.502 SM2Sign-with-SHA1
1.2.156.10197.1.503 SM2Sign-with-SHA256
1.2.156.10197.1.504 SM2Sign-with-SHA511
1.2.156.10197.1.505 SM2Sign-with-SHA224
1.2.156.10197.1.506 SM2Sign-with-SHA384
1.2.156.10197.1.507 SM2Sign-with-RMD160

@davidkhala , do we need add sample for above all?

sm2/3 factory

make a factory to create sm2/3 basic actions for

  • pem generate.
  • cert generate.
  • digest and sign/verify.
  • encrypt/decrypt.
  • key load.
  • others?

@xiaohui249 , any other suggestions?

upgrade bouncycastle to latest

  1. upgrade bouncycastle to latest
  2. add test case for hash256sm2 etc support
  3. add mvn repo mirror as download from main repo is too slow some time due to network issue

clean up: gradle

我发现有一个gradle jar放在代码当中,它是必要的么?

SM4Util重构后的问题

看了synchronized同步代码,以及SM4Util的公开构造方法。我的想法:1、改成synchronized,目的应该是避免一个SM4Util单实例使用出现线程安全问题,但是影响了性能,而且并没有从实质上解决线程安全问题,线程安全问题是由Cipher引起的,而Cipher对象是公用的,无法保证调用者单例使用;2、SM4Util的构造方法是public的,所以从这个层面来讲,上一步的synchronized意义不大,而且实例化SM4Util时,Cipher.getInstance仍然要执行一遍。

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.