├── 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 | 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 | --------------------------------------------------------------------------------