├── README.md
├── build
├── favicon.ico
├── logo-192.png
├── logo-512.png
├── manifest.json
└── robots.txt
├── electron.js
├── package.json
├── public
├── favicon.ico
├── index.html
├── logo-192.png
├── logo-512.png
├── manifest.json
└── robots.txt
└── src
├── App.css
├── App.js
├── App.test.js
├── index.css
├── index.js
├── reportWebVitals.js
└── setupTests.js
/README.md:
--------------------------------------------------------------------------------
1 | # API Key Generator
2 |
3 | This project was bootstrapped with:
4 |
5 | [React](https://github.com/facebook/react).
6 |
7 | [Electron](https://github.com/electron/electron).
8 |
9 | [Ant-Design](https://github.com/ant-design/ant-design).
10 |
11 |
12 | ## Build from source
13 |
14 | In the project directory, you can run:
15 |
16 | ### `npm install`
17 |
18 | Install dependencies for app.
19 |
20 | ### `npm run build`
21 |
22 | Builds the app for production to the `build` folder.\
23 | It correctly bundles React in production mode and optimizes the build for the best performance.
24 |
25 | ### `npm run start`
26 |
27 | Runs the app in the development mode.\
28 | Open [http://localhost:3000](http://localhost:3000) to view it in your browser.
29 |
30 | The page will reload when you make changes.\
31 | You may also see any lint errors in the console.
32 |
33 | ### `npm run dist`
34 |
35 | Package app to MacOS .dmg, Window .exe And Linux .AppImage file.
36 |
37 | ## License
38 |
39 | MIT
--------------------------------------------------------------------------------
/build/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BitgetLimited/api-rsa-generator/830ddde86722645785d781ecfa7caa024d2eb292/build/favicon.ico
--------------------------------------------------------------------------------
/build/logo-192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BitgetLimited/api-rsa-generator/830ddde86722645785d781ecfa7caa024d2eb292/build/logo-192.png
--------------------------------------------------------------------------------
/build/logo-512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BitgetLimited/api-rsa-generator/830ddde86722645785d781ecfa7caa024d2eb292/build/logo-512.png
--------------------------------------------------------------------------------
/build/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo-192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo-512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/build/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/electron.js:
--------------------------------------------------------------------------------
1 | const { app, BrowserWindow } = require('electron');
2 |
3 | // window对象的全局引用
4 | let mainWindow
5 | function createWindow() {
6 |
7 | mainWindow = new BrowserWindow({ width: 800, height: 600 })
8 |
9 | // 开发环境
10 | // mainWindow.loadURL('http://localhost:3000/');
11 |
12 | // 生产环境
13 | mainWindow.loadFile(`${__dirname}/build/index.html`);
14 |
15 |
16 | // 打开开发者工具,默认不打开
17 | // mainWindow.webContents.openDevTools()
18 |
19 | // 关闭window时触发下列事件.
20 | mainWindow.on('closed', function () {
21 | mainWindow = null
22 | })
23 | }
24 |
25 | app.on('ready', createWindow);
26 |
27 | // 所有窗口关闭时退出应用.
28 | app.on('window-all-closed', function () {
29 | if (process.platform !== 'darwin') {
30 | app.quit()
31 | }
32 | })
33 |
34 | app.on('activate', function () {
35 |
36 | if (mainWindow === null) {
37 | createWindow()
38 | }
39 | })
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ApiRSAGenerator",
3 | "version": "1.0.0",
4 | "description": "Used for openapi's RSA key pair generate.",
5 | "private": true,
6 | "main": "electron.js",
7 | "homepage": "./",
8 | "license": "MIT",
9 | "author": {
10 | "name": "Bitget",
11 | "email": "api@bitget.com",
12 | "url": "https://www.bitget.com"
13 | },
14 | "dependencies": {
15 | },
16 | "scripts": {
17 | "electron-dev": "electron .",
18 | "start": "react-scripts start",
19 | "build": "react-scripts build",
20 | "test": "react-scripts test",
21 | "eject": "react-scripts eject",
22 | "dist": "electron-builder -mwl"
23 | },
24 | "eslintConfig": {
25 | "extends": [
26 | "react-app",
27 | "react-app/jest"
28 | ]
29 | },
30 | "browserslist": {
31 | "production": [
32 | ">0.2%",
33 | "not dead",
34 | "not op_mini all"
35 | ],
36 | "development": [
37 | "last 1 chrome version",
38 | "last 1 firefox version",
39 | "last 1 safari version"
40 | ]
41 | },
42 | "devDependencies": {
43 | "@testing-library/jest-dom": "^5.16.5",
44 | "@testing-library/react": "^13.4.0",
45 | "@testing-library/user-event": "^13.5.0",
46 | "antd": "^5.1.4",
47 | "crypto-browserify": "^3.12.0",
48 | "react": "^18.2.0",
49 | "react-dom": "^18.2.0",
50 | "react-scripts": "4.0.3",
51 | "web-vitals": "^2.1.4",
52 | "electron": "^22.0.1",
53 | "electron-builder": "^23.6.0"
54 | },
55 | "build": {
56 | "appId": "api-rsa-generator",
57 | "productName": "ApiRSAGenerator",
58 | "extends": null,
59 | "files": [
60 | "build/**/*",
61 | "electron.js"
62 | ],
63 | "mac": {
64 | "icon": "public/logo-512.png",
65 | "target": {
66 | "target": "dmg",
67 | "arch": [
68 | "universal"
69 | ]
70 | }
71 | },
72 | "win": {
73 | "icon": "public/logo-512.png",
74 | "target": {
75 | "target": "nsis",
76 | "arch": [
77 | "x64"
78 | ]
79 | }
80 | },
81 | "linux": {
82 | "icon": "public/logo-512.png",
83 | "target": {
84 | "target": "AppImage",
85 | "arch": [
86 | "x64"
87 | ]
88 | }
89 | }
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BitgetLimited/api-rsa-generator/830ddde86722645785d781ecfa7caa024d2eb292/public/favicon.ico
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
17 |
18 |
27 | Api RSA Generator
28 |
29 |
30 |
31 |
32 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/public/logo-192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BitgetLimited/api-rsa-generator/830ddde86722645785d781ecfa7caa024d2eb292/public/logo-192.png
--------------------------------------------------------------------------------
/public/logo-512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BitgetLimited/api-rsa-generator/830ddde86722645785d781ecfa7caa024d2eb292/public/logo-512.png
--------------------------------------------------------------------------------
/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo-192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo-512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | width: 80%;
3 | margin-left: 10%;
4 | margin-right: 10%;
5 | }
6 |
--------------------------------------------------------------------------------
/src/App.js:
--------------------------------------------------------------------------------
1 | import './App.css';
2 | import { Button, Select, Space, Card, Row, Col } from 'antd';
3 | import TextArea from 'antd/es/input/TextArea';
4 | import { useState } from "react";
5 | import "crypto";
6 |
7 | async function generateKeysWithBits (bits) {
8 | const result = await crypto.subtle.generateKey(
9 | {
10 | name: "RSASSA-PKCS1-v1_5",
11 | modulusLength: parseInt(bits),
12 | publicExponent: new Uint8Array([1, 0, 1]),
13 | hash: "SHA-256"
14 | },
15 | true,
16 | ["sign", "verify"]
17 | ).then(function(res){
18 | return res
19 | });
20 |
21 | let priv = await crypto.subtle.exportKey("pkcs8", result.privateKey)
22 | priv = Buffer.from(priv).toString('base64')
23 | priv = priv.match(/.{1,64}/g).join('\n')
24 | let privStr = "-----BEGIN PRIVATE KEY-----\n" + priv + "\n-----END PRIVATE KEY-----"
25 |
26 | let pub = await crypto.subtle.exportKey("spki", result.publicKey)
27 | pub = Buffer.from(pub).toString('base64')
28 | pub = pub.match(/.{1,64}/g).join('\n')
29 | let pubStr = "-----BEGIN PUBLIC KEY-----\n" + pub + "\n-----END PUBLIC KEY-----"
30 | return {"priv": privStr, "pub": pubStr}
31 | }
32 |
33 | function App() {
34 | var selectVal = "2048"
35 | const [loading, setLoading] = useState(Boolean)
36 | const [privVal, setPrivVal] = useState("")
37 | const [pubVal, setPubVal] = useState("")
38 |
39 | const generateKeys = async () => {
40 | setLoading(true)
41 | setPrivVal("")
42 | setPubVal("")
43 | const res = await generateKeysWithBits(parseInt(selectVal))
44 | setPrivVal(res.priv)
45 | setPubVal(res.pub)
46 | setLoading(false)
47 | }
48 | const copyPriv = async () => {
49 | navigator.clipboard.writeText(privVal)
50 | }
51 | const copyPub = async () => {
52 | navigator.clipboard.writeText(pubVal)
53 | }
54 |
55 | return (
56 |
57 |
58 |
59 | Generate Keys
60 |
61 |
62 | You can generate an RSA PKCS#8 private key and public key of 2048-bit(recommend) or 4096-bit.
63 |
64 |
65 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 | );
101 | }
102 |
103 | export default App;
104 |
--------------------------------------------------------------------------------
/src/App.test.js:
--------------------------------------------------------------------------------
1 | import { render, screen } from '@testing-library/react';
2 | import App from './App';
3 |
4 | test('renders learn react link', () => {
5 | render();
6 | const linkElement = screen.getByText(/learn react/i);
7 | expect(linkElement).toBeInTheDocument();
8 | });
9 |
--------------------------------------------------------------------------------
/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
5 | sans-serif;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | }
9 |
10 | code {
11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
12 | monospace;
13 | }
14 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom/client';
3 | import './index.css';
4 | import App from './App';
5 | import reportWebVitals from './reportWebVitals';
6 |
7 | const root = ReactDOM.createRoot(document.getElementById('root'));
8 | root.render(
9 |
10 |
11 |
12 | );
13 |
14 | // If you want to start measuring performance in your app, pass a function
15 | // to log results (for example: reportWebVitals(console.log))
16 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
17 | reportWebVitals();
18 |
--------------------------------------------------------------------------------
/src/reportWebVitals.js:
--------------------------------------------------------------------------------
1 | const reportWebVitals = onPerfEntry => {
2 | if (onPerfEntry && onPerfEntry instanceof Function) {
3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
4 | getCLS(onPerfEntry);
5 | getFID(onPerfEntry);
6 | getFCP(onPerfEntry);
7 | getLCP(onPerfEntry);
8 | getTTFB(onPerfEntry);
9 | });
10 | }
11 | };
12 |
13 | export default reportWebVitals;
14 |
--------------------------------------------------------------------------------
/src/setupTests.js:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom';
6 |
--------------------------------------------------------------------------------