{"id":13630843,"url":"https://github.com/aliyun/gm-jsse","last_synced_at":"2025-04-17T17:31:48.857Z","repository":{"id":49397755,"uuid":"305567067","full_name":"aliyun/gm-jsse","owner":"aliyun","description":"开源国密通信纯 Java JSSE 实现","archived":false,"fork":false,"pushed_at":"2024-03-18T02:25:19.000Z","size":197,"stargazers_count":120,"open_issues_count":9,"forks_count":42,"subscribers_count":9,"default_branch":"master","last_synced_at":"2024-09-18T05:28:03.743Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aliyun.png","metadata":{"files":{"readme":"README-CN.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-10-20T02:23:47.000Z","updated_at":"2024-05-11T05:45:06.000Z","dependencies_parsed_at":"2023-11-13T04:26:45.131Z","dependency_job_id":"92571d37-c4db-48d9-9fcc-d27c209ea5e9","html_url":"https://github.com/aliyun/gm-jsse","commit_stats":null,"previous_names":["aliyun/alibabacloud-gm-jsse"],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aliyun%2Fgm-jsse","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aliyun%2Fgm-jsse/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aliyun%2Fgm-jsse/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aliyun%2Fgm-jsse/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aliyun","download_url":"https://codeload.github.com/aliyun/gm-jsse/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249360018,"owners_count":21257152,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T22:02:00.844Z","updated_at":"2025-04-17T17:31:48.462Z","avatar_url":"https://github.com/aliyun.png","language":"Java","funding_links":[],"categories":["Java","安全"],"sub_categories":[],"readme":"[English](./README.md) | 简体中文\n\n# 国密 JSSE\n\n\u003cp align=\"center\"\u003e\n\u003ca href=\"https://search.maven.org/search?q=g:%22com.aliyun%22%20AND%20a:%22gmsse%22\"\u003e\u003cimg src=\"https://img.shields.io/maven-central/v/com.aliyun/gmsse.svg?label=Maven%20Central\" alt=\"Latest Stable Version\"/\u003e\u003c/a\u003e\n\u003ca href=\"https://github.com/aliyun/gm-jsse/actions/workflows/maven.yml\"\u003e\u003cimg src=\"https://github.com/aliyun/gm-jsse/actions/workflows/maven.yml/badge.svg\" alt=\"Java CI with Maven\"/\u003e\u003c/a\u003e\n\u003ca href=\"https://ci.appveyor.com/project/JacksonTian/alibabacloud-gm-jsse/branch/master\"\u003e\u003cimg src=\"https://ci.appveyor.com/api/projects/status/7xwn4tw8gcl86im5/branch/master?svg=true\"/\u003e\u003c/a\u003e\n\u003ca href=\"https://codecov.io/gh/aliyun/gm-jsse\"\u003e\u003cimg src=\"https://codecov.io/gh/aliyun/gm-jsse/branch/master/graph/badge.svg\"/\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n## 环境要求\n\n- 需要 JDK 1.7 或以上.\n\n## 安装依赖\n\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003ecom.aliyun\u003c/groupId\u003e\n    \u003cartifactId\u003egmsse\u003c/artifactId\u003e\n    \u003cversion\u003e{{使用maven标签所显示的版本}}\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n## 快速使用\n\n```java\nimport javax.net.ssl.HttpsURLConnection;\nimport javax.net.ssl.SSLContext;\nimport javax.net.ssl.SSLSocketFactory;\nimport java.net.URL;\n\nimport com.aliyun.gmsse.GMProvider;\n\npublic class Main {\n\n    public static void main(String[] args) throws Exception {\n        // 初始化 SSLSocketFactory\n        GMProvider provider = new GMProvider();\n        SSLContext sc = SSLContext.getInstance(\"TLS\", provider);\n        sc.init(null, null, null);\n        SSLSocketFactory ssf = sc.getSocketFactory();\n\n        URL serverUrl = new URL(\"https://xxx/\");\n        HttpsURLConnection conn = (HttpsURLConnection) serverUrl.openConnection();\n        conn.setRequestMethod(\"GET\");\n        // 设置 SSLSocketFactory\n        conn.setSSLSocketFactory(ssf);\n        conn.connect();\n        System.out.println(\"used cipher suite:\");\n        System.out.println(conn.getCipherSuite());\n    }\n}\n```\n\n在新的版本中，GM-JSSE 增加了对服务端证书和 CA 证书的校验，如果 CA 根证书没有导入在系统中，可能会遇到校验错误。这时，你需要通过传递信任管理器的形式来传入 CA 证书。\n\n```java\n    BouncyCastleProvider bc = new BouncyCastleProvider();\n    KeyStore ks = KeyStore.getInstance(\"JKS\");\n    CertificateFactory cf = CertificateFactory.getInstance(\"X.509\", bc);\n    FileInputStream is = new FileInputStream(\"/path/to/ca_cert\");\n    X509Certificate cert = (X509Certificate) cf.generateCertificate(is);\n    ks.load(null, null);\n    ks.setCertificateEntry(\"gmca\", cert);\n\n    TrustManagerFactory tmf = TrustManagerFactory.getInstance(\"X509\", provider);\n    tmf.init(ks);\n\n    sc.init(null, tmf.getTrustManagers(), null);\n    SSLSocketFactory ssf = sc.getSocketFactory();\n```\n\n### 双向认证\n\n双向认证中，客户端需要传入双证书。\n\n```java\n\n    public static X509Certificate loadCertificate(String path) throws KeyStoreException, CertificateException, FileNotFoundException {\n        BouncyCastleProvider bc = new BouncyCastleProvider();\n        CertificateFactory cf = CertificateFactory.getInstance(\"X.509\", bc);\n        InputStream is = Server.class.getClassLoader().getResourceAsStream(path);\n        X509Certificate cert = (X509Certificate) cf.generateCertificate(is);\n        return cert;\n    }\n\n    public static PrivateKey loadPrivateKey(String path) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {\n        InputStream is = Server.class.getClassLoader().getResourceAsStream(path);\n        InputStreamReader inputStreamReader = new InputStreamReader(is);\n        BufferedReader bufferedReader = new BufferedReader(inputStreamReader);\n        StringBuilder sb = new StringBuilder();\n        String line = null;\n            while ((line = bufferedReader.readLine()) != null){\n            if (line.startsWith(\"-\")){\n                continue;\n            }\n            sb.append(line).append(\"\\n\");\n        }\n        String ecKey = sb.toString().replaceAll(\"\\\\r\\\\n|\\\\r|\\\\n\", \"\");\n        Base64.Decoder base64Decoder = Base64.getDecoder();\n        byte[] keyByte = base64Decoder.decode(ecKey.getBytes(StandardCharsets.UTF_8));\n        PKCS8EncodedKeySpec eks2 = new PKCS8EncodedKeySpec(keyByte);\n        KeyFactory keyFactory = KeyFactory.getInstance(\"EC\", new BouncyCastleProvider());\n        PrivateKey privateKey = keyFactory.generatePrivate(eks2);\n        return privateKey;\n    }\n\n    KeyStore ks = KeyStore.getInstance(\"PKCS12\", new BouncyCastleProvider());\n    ks.load(null, null);\n\n    // 传入签名证书\n    ks.setKeyEntry(\"sign\", loadPrivateKey(\"sm2/client_sign.key\"), new char[0], new X509Certificate[] {\n        loadCertificate(\"sm2/client_sign.crt\")\n    });\n    // 传入加密证书\n    ks.setKeyEntry(\"enc\", Server.loadPrivateKey(\"sm2/client_enc.key\"), new char[0], new X509Certificate[] {\n        oadCertificate(\"sm2/client_enc.crt\")\n    });\n\n    KeyManagerFactory kmf = KeyManagerFactory.getInstance(\"SunX509\");\n    kmf.init(ks, new char[0]);\n\n    // 传入根证书\n    ks.setCertificateEntry(\"gmca\", loadCertificate(\"sm2/chain-ca.crt\"));\n\n    TrustManagerFactory tmf = TrustManagerFactory.getInstance(\"X509\", provider);\n    tmf.init(ks);\n\n    sc.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);\n    SSLSocketFactory ssf = sc.getSocketFactory();\n```\n\n## 问题\n\n[Opening an Issue](https://github.com/aliyun/gm-jsse/issues/new), Issues not conforming to the guidelines may be closed immediately.\n\n## 发行说明\n\n每个版本的详细更改记录在[发行说明](https://github.com/aliyun/gm-jsse/releases).\n\n## 许可证\n\n[Apache-2.0](http://www.apache.org/licenses/LICENSE-2.0)\n\nCopyright (c) 2009-present, Alibaba Cloud All rights reserved.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faliyun%2Fgm-jsse","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faliyun%2Fgm-jsse","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faliyun%2Fgm-jsse/lists"}