├── .clang-format ├── .github └── workflows │ ├── ci.yml │ └── release.yml ├── .gitignore ├── CHANGES ├── LICENSE ├── README.md ├── TongsuoToolbox_v01.pro ├── about.cpp ├── about.h ├── about.ui ├── certs.qrc ├── certs ├── ca.key ├── ca.pem ├── subca.key └── subca.pem ├── main.cpp ├── mainwindow.cpp ├── mainwindow.h ├── mainwindow.ui ├── randnum.cpp ├── randnum.h ├── randnum.ui ├── sm2.cpp ├── sm2.h ├── sm2cert.cpp ├── sm2cert.h ├── sm2cert.ui ├── sm2encrypt.cpp ├── sm2encrypt.h ├── sm2encrypt.ui ├── sm2key.cpp ├── sm2key.h ├── sm2key.ui ├── sm2signverify.cpp ├── sm2signverify.h ├── sm2signverify.ui ├── sm3hash.cpp ├── sm3hash.h ├── sm3hash.ui ├── sm4encrypt.cpp ├── sm4encrypt.h ├── sm4encrypt.ui ├── tlcpclient.cpp ├── tlcpclient.h ├── tlcpclient.ui ├── tserror.cpp ├── tserror.h └── version.h /.clang-format: -------------------------------------------------------------------------------- 1 | # clang-format >= 15 2 | --- 3 | Language: Cpp 4 | AccessModifierOffset: -4 5 | AlignAfterOpenBracket: Align 6 | AlignConsecutiveAssignments: false 7 | AlignConsecutiveDeclarations: false 8 | AlignEscapedNewlines: DontAlign 9 | AlignOperands: true 10 | AlignTrailingComments: true 11 | AllowAllParametersOfDeclarationOnNextLine: true 12 | AllowShortBlocksOnASingleLine: Never 13 | AllowShortCaseLabelsOnASingleLine: false 14 | AllowShortFunctionsOnASingleLine: Inline 15 | AllowShortIfStatementsOnASingleLine: false 16 | AllowShortLoopsOnASingleLine: false 17 | AlwaysBreakAfterReturnType: None 18 | AlwaysBreakBeforeMultilineStrings: false 19 | AlwaysBreakTemplateDeclarations: Yes 20 | BinPackArguments: false 21 | BinPackParameters: false 22 | BraceWrapping: 23 | AfterClass: true 24 | AfterControlStatement: Never 25 | AfterEnum: false 26 | AfterFunction: true 27 | AfterNamespace: false 28 | AfterObjCDeclaration: false 29 | AfterStruct: true 30 | AfterUnion: false 31 | BeforeCatch: false 32 | BeforeElse: false 33 | IndentBraces: false 34 | SplitEmptyFunction: false 35 | SplitEmptyRecord: false 36 | SplitEmptyNamespace: false 37 | BreakBeforeBinaryOperators: All 38 | BreakBeforeBraces: Custom 39 | BreakBeforeInheritanceComma: false 40 | BreakBeforeTernaryOperators: true 41 | BreakConstructorInitializersBeforeComma: false 42 | BreakConstructorInitializers: BeforeComma 43 | BreakAfterJavaFieldAnnotations: false 44 | BreakStringLiterals: true 45 | ColumnLimit: 100 46 | CommentPragmas: '^ IWYU pragma:' 47 | CompactNamespaces: false 48 | ConstructorInitializerAllOnOneLineOrOnePerLine: false 49 | ConstructorInitializerIndentWidth: 4 50 | ContinuationIndentWidth: 4 51 | Cpp11BracedListStyle: true 52 | DerivePointerAlignment: false 53 | DisableFormat: false 54 | ExperimentalAutoDetectBinPacking: false 55 | FixNamespaceComments: true 56 | ForEachMacros: 57 | - forever # avoids { wrapped to next line 58 | - foreach 59 | - Q_FOREACH 60 | - BOOST_FOREACH 61 | IncludeCategories: 62 | - Regex: '^ 多数功能都支持用户自输入密钥 7 | 8 | - 随机数生成 9 | - SM2密钥对生成 10 | - SM2加解密 11 | - SM2签名与验签 12 | - SM3摘要 13 | - SM4加解密 14 | - 签发SM2证书 15 | - TLCP客户端 16 | 17 | # 配置与安装 18 | 19 | 可以直接安装使用该应用程序,或使用源码在本地使用QT启动。 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /TongsuoToolbox_v01.pro: -------------------------------------------------------------------------------- 1 | QT += core gui 2 | 3 | QT += network 4 | 5 | greaterThan(QT_MAJOR_VERSION, 4): QT += widgets 6 | 7 | CONFIG += c++17 8 | 9 | # You can make your code fail to compile if it uses deprecated APIs. 10 | # In order to do so, uncomment the following line. 11 | #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 12 | 13 | TARGET=tsapp 14 | 15 | SOURCES += \ 16 | about.cpp \ 17 | main.cpp \ 18 | mainwindow.cpp \ 19 | randnum.cpp \ 20 | sm2.cpp \ 21 | sm2cert.cpp \ 22 | sm2encrypt.cpp \ 23 | sm2key.cpp \ 24 | sm2signverify.cpp \ 25 | sm3hash.cpp \ 26 | sm4encrypt.cpp \ 27 | tlcpclient.cpp \ 28 | tserror.cpp 29 | 30 | HEADERS += \ 31 | about.h \ 32 | mainwindow.h \ 33 | randnum.h \ 34 | sm2.h \ 35 | sm2cert.h \ 36 | sm2encrypt.h \ 37 | sm2key.h \ 38 | sm2signverify.h \ 39 | sm3hash.h \ 40 | sm4encrypt.h \ 41 | tlcpclient.h \ 42 | tserror.h \ 43 | version.h 44 | 45 | # Default rules for deployment. 46 | target.path = $$(PREFIX) 47 | !isEmpty(target.path): INSTALLS += target 48 | 49 | win32: LIBS += -ladvapi32 -lcrypt32 -lgdi32 -luser32 -lws2_32 -L$$(TONGSUO_HOME)/lib -llibssl -llibcrypto 50 | else:unix: LIBS += -L$$(TONGSUO_HOME)/lib -lssl -lcrypto 51 | 52 | INCLUDEPATH += $$(TONGSUO_HOME)/include 53 | DEPENDPATH += $$(TONGSUO_HOME)/include 54 | 55 | win32-g++: PRE_TARGETDEPS += $$(TONGSUO_HOME)/lib/libcrypto.lib.a $$(TONGSUO_HOME)/lib/libssl.lib.a 56 | else:win32:!win32-g++: PRE_TARGETDEPS += $$(TONGSUO_HOME)/lib/libcrypto.lib $$(TONGSUO_HOME)/lib/libssl.lib 57 | else:unix: PRE_TARGETDEPS += $$(TONGSUO_HOME)/lib/libssl.a $$(TONGSUO_HOME)/lib/libcrypto.a 58 | 59 | FORMS += \ 60 | about.ui \ 61 | mainwindow.ui \ 62 | randnum.ui \ 63 | sm2cert.ui \ 64 | sm2encrypt.ui \ 65 | sm2key.ui \ 66 | sm2signverify.ui \ 67 | sm3hash.ui \ 68 | sm4encrypt.ui \ 69 | tlcpclient.ui 70 | 71 | RESOURCES += \ 72 | certs.qrc 73 | 74 | DISTFILES += 75 | -------------------------------------------------------------------------------- /about.cpp: -------------------------------------------------------------------------------- 1 | #include "about.h" 2 | #include "ui_about.h" 3 | #include "version.h" 4 | 5 | About::About(QWidget *parent) 6 | : QDialog(parent) 7 | , ui(new Ui::About) 8 | { 9 | ui->setupUi(this); 10 | 11 | QString text = ui->textBrowser->toHtml(); 12 | 13 | text.replace("|version|", version); 14 | 15 | ui->textBrowser->setHtml(text); 16 | } 17 | 18 | About::~About() 19 | { 20 | delete ui; 21 | } 22 | 23 | void About::on_pushButton_clicked() 24 | { 25 | this->close(); 26 | } 27 | -------------------------------------------------------------------------------- /about.h: -------------------------------------------------------------------------------- 1 | #ifndef ABOUT_H 2 | #define ABOUT_H 3 | 4 | #include 5 | 6 | namespace Ui { 7 | class About; 8 | } 9 | 10 | class About : public QDialog 11 | { 12 | Q_OBJECT 13 | 14 | public: 15 | explicit About(QWidget *parent = nullptr); 16 | ~About(); 17 | 18 | private slots: 19 | void on_pushButton_clicked(); 20 | 21 | private: 22 | Ui::About *ui; 23 | }; 24 | 25 | #endif // ABOUT_H 26 | -------------------------------------------------------------------------------- /about.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | About 4 | 5 | 6 | 7 | 0 8 | 0 9 | 400 10 | 300 11 | 12 | 13 | 14 | About tsapp 15 | 16 | 17 | 18 | 19 | 20 | 关闭 21 | 22 | 23 | 24 | 25 | 26 | 27 | Qt::Horizontal 28 | 29 | 30 | 31 | 40 32 | 20 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | About tsapp 41 | 42 | 43 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> 44 | <html><head><meta name="qrichtext" content="1" /><meta charset="utf-8" /><title>About tsapp</title><style type="text/css"> 45 | p, li { white-space: pre-wrap; } 46 | hr { height: 1px; border-width: 0; } 47 | li.unchecked::marker { content: "\2610"; } 48 | li.checked::marker { content: "\2612"; } 49 | </style></head><body style=" font-family:'.AppleSystemUIFont'; font-size:13pt; font-weight:400; font-style:normal;"> 50 | <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:18pt; font-weight:700;">铜锁密码工具箱(tsapp)|version|</span></p> 51 | <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> 52 | <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">铜锁密码工具箱(tsapp)基于铜锁密码库(<a href="https://github.com/Tongsuo-Project/Tongsuo"><span style=" text-decoration: underline; color:#094fd1;">https://github.com/Tongsuo-Project/Tongsuo</span></a>)提供的密码学能力开发的商用密码工具箱桌面应用程序。</p> 53 | <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> 54 | <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">图形用户界面基于Qt框架开发。</p> 55 | <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> 56 | <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">本项目地址<a href="https://github.com/Tongsuo-Project/tsapp"><span style=" text-decoration: underline; color:#094fd1;">https://github.com/Tongsuo-Project/tsapp</span></a>,欢迎提交issue和PR。</p></body></html> 57 | 58 | 59 | true 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /certs.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | certs/subca.pem 4 | certs/subca.key 5 | 6 | 7 | -------------------------------------------------------------------------------- /certs/ca.key: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIGHAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBG0wawIBAQQgTSHZtff0A3YHhojG 3 | HKIu0odvPip6+39lsguxDH3m+TmhRANCAARC7ZCfZAaqCbMEh1K3pEj2S6/ty2yN 4 | C6x0zIbyxq+mib7qTssQcLrsPMe1EGb2FZQpGk4L9mOzBNlijoi1ocb5 5 | -----END PRIVATE KEY----- 6 | -------------------------------------------------------------------------------- /certs/ca.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIB3jCCAYSgAwIBAgIBAjAKBggqgRzPVQGDdTBFMQswCQYDVQQGEwJBQjELMAkG 3 | A1UECAwCQ0QxCzAJBgNVBAoMAkdIMQswCQYDVQQLDAJJSjEPMA0GA1UEAwwGQ0Eg 4 | U00yMCAXDTI0MDcwNzA0Mjc0NVoYDzIxMjQwNjEzMDQyNzQ1WjBFMQswCQYDVQQG 5 | EwJBQjELMAkGA1UECAwCQ0QxCzAJBgNVBAoMAkdIMQswCQYDVQQLDAJJSjEPMA0G 6 | A1UEAwwGQ0EgU00yMFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAEQu2Qn2QGqgmz 7 | BIdSt6RI9kuv7ctsjQusdMyG8savpom+6k7LEHC67DzHtRBm9hWUKRpOC/ZjswTZ 8 | Yo6ItaHG+aNjMGEwHQYDVR0OBBYEFGPkDCglafjEeeT2wufS/PqKqSP+MB8GA1Ud 9 | IwQYMBaAFGPkDCglafjEeeT2wufS/PqKqSP+MA8GA1UdEwEB/wQFMAMBAf8wDgYD 10 | VR0PAQH/BAQDAgGGMAoGCCqBHM9VAYN1A0gAMEUCIQDOKNIcpCOnL/qFC9nYHSY0 11 | fHWiGgZLLVFkamCN0meRNgIgUfW1xK+7rZddJSHqJKIeHJp28PlKBXY8oIuGhhEz 12 | EqQ= 13 | -----END CERTIFICATE----- 14 | -------------------------------------------------------------------------------- /certs/subca.key: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIGHAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBG0wawIBAQQgC2yI3oPT4cnM8fGf 3 | J/emyP9/Qr87/x1RO5sNMnm5ioqhRANCAAR73c9xN7bdOrqUQhe/77qxwerRbzZe 4 | wZ65DXOMgIztuCiCEQLh0CfjPLV98LxHbUhTc1EJWhDGofTqh8VFQNYj 5 | -----END PRIVATE KEY----- 6 | -------------------------------------------------------------------------------- /certs/subca.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIB4zCCAYqgAwIBAgIBAjAKBggqgRzPVQGDdTBFMQswCQYDVQQGEwJBQjELMAkG 3 | A1UECAwCQ0QxCzAJBgNVBAoMAkdIMQswCQYDVQQLDAJJSjEPMA0GA1UEAwwGQ0Eg 4 | U00yMCAXDTI0MDcwNzA0Mjc0NloYDzIxMjQwNjEzMDQyNzQ2WjBIMQswCQYDVQQG 5 | EwJBQjELMAkGA1UECAwCQ0QxCzAJBgNVBAoMAkdIMQswCQYDVQQLDAJJSjESMBAG 6 | A1UEAwwJU1VCQ0EgU00yMFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAEe93PcTe2 7 | 3Tq6lEIXv++6scHq0W82XsGeuQ1zjICM7bgoghEC4dAn4zy1ffC8R21IU3NRCVoQ 8 | xqH06ofFRUDWI6NmMGQwHQYDVR0OBBYEFCi8tdpCMx+yoWdWdO3IZ6xxDhljMB8G 9 | A1UdIwQYMBaAFGPkDCglafjEeeT2wufS/PqKqSP+MBIGA1UdEwEB/wQIMAYBAf8C 10 | AQAwDgYDVR0PAQH/BAQDAgGGMAoGCCqBHM9VAYN1A0cAMEQCIH6UJaA1ppUtSbHn 11 | 3JRGdRHpVKgGaxRkqIVIrfgLnG8IAiBrcRv26xSHRe1eFT9BoJkIiFNTb/gbPdjS 12 | 0kQ4AdEHkQ== 13 | -----END CERTIFICATE----- 14 | -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- 1 | #include "mainwindow.h" 2 | #include 3 | #include 4 | 5 | BIO *bio_err = NULL; 6 | 7 | int main(int argc, char *argv[]) 8 | { 9 | if (!OPENSSL_init_ssl(OPENSSL_INIT_NO_LOAD_CONFIG, NULL)) 10 | return 1; 11 | 12 | bio_err = BIO_new_fp(stderr, BIO_NOCLOSE | BIO_FP_TEXT); 13 | 14 | QApplication a(argc, argv); 15 | MainWindow w; 16 | w.show(); 17 | return a.exec(); 18 | } 19 | -------------------------------------------------------------------------------- /mainwindow.cpp: -------------------------------------------------------------------------------- 1 | #include "mainwindow.h" 2 | #include "ui_mainwindow.h" 3 | 4 | MainWindow::MainWindow(QWidget *parent) 5 | : QMainWindow(parent) 6 | , ui(new Ui::MainWindow) 7 | { 8 | ui->setupUi(this); 9 | about = new About(); 10 | } 11 | 12 | MainWindow::~MainWindow() 13 | { 14 | delete ui; 15 | } 16 | 17 | void MainWindow::on_action_about_triggered() 18 | { 19 | about->show(); 20 | } 21 | 22 | void MainWindow::on_action_exit_triggered() 23 | { 24 | this->close(); 25 | } 26 | 27 | void MainWindow::on_listWidget_currentRowChanged(int currentRow) 28 | { 29 | this->ui->stackedWidget->setCurrentIndex(currentRow); 30 | } 31 | -------------------------------------------------------------------------------- /mainwindow.h: -------------------------------------------------------------------------------- 1 | #ifndef MAINWINDOW_H 2 | #define MAINWINDOW_H 3 | 4 | #include "about.h" 5 | #include 6 | 7 | namespace Ui { 8 | class MainWindow; 9 | } 10 | 11 | class MainWindow : public QMainWindow 12 | { 13 | Q_OBJECT 14 | 15 | public: 16 | explicit MainWindow(QWidget *parent = nullptr); 17 | ~MainWindow(); 18 | 19 | private slots: 20 | void on_action_about_triggered(); 21 | 22 | void on_action_exit_triggered(); 23 | 24 | void on_listWidget_currentRowChanged(int currentRow); 25 | 26 | private: 27 | Ui::MainWindow *ui; 28 | 29 | About *about; 30 | }; 31 | 32 | #endif // MAINWINDOW_H 33 | -------------------------------------------------------------------------------- /mainwindow.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | MainWindow 4 | 5 | 6 | 7 | 0 8 | 0 9 | 800 10 | 600 11 | 12 | 13 | 14 | 铜锁密码工具箱(tsapp) 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 200 25 | 16777215 26 | 27 | 28 | 29 | 30 | 随机数生成 31 | 32 | 33 | 34 | 35 | SM2密钥生成 36 | 37 | 38 | 39 | 40 | SM2签名验签 41 | 42 | 43 | 44 | 45 | SM2加解密 46 | 47 | 48 | 49 | 50 | SM3杂凑 51 | 52 | 53 | 54 | 55 | SM4加解密 56 | 57 | 58 | 59 | 60 | 双证书签发 61 | 62 | 63 | 64 | 65 | TLCP客户端 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 0 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 0 93 | 0 94 | 800 95 | 24 96 | 97 | 98 | 99 | 100 | tsapp 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 关于tsapp 112 | 113 | 114 | 115 | 116 | 退出tsapp 117 | 118 | 119 | 120 | 121 | 122 | RandNum 123 | QWidget 124 |
randnum.h
125 | 1 126 |
127 | 128 | Sm2Key 129 | QWidget 130 |
sm2key.h
131 | 1 132 |
133 | 134 | Sm2SignVerify 135 | QWidget 136 |
sm2signverify.h
137 | 1 138 |
139 | 140 | Sm2Encrypt 141 | QWidget 142 |
sm2encrypt.h
143 | 1 144 |
145 | 146 | Sm3Hash 147 | QWidget 148 |
sm3hash.h
149 | 1 150 |
151 | 152 | Sm4encrypt 153 | QWidget 154 |
sm4encrypt.h
155 | 1 156 |
157 | 158 | Sm2Cert 159 | QWidget 160 |
sm2cert.h
161 | 1 162 |
163 | 164 | TLCPclient 165 | QWidget 166 |
tlcpclient.h
167 | 1 168 |
169 |
170 | 171 | 172 |
173 | -------------------------------------------------------------------------------- /randnum.cpp: -------------------------------------------------------------------------------- 1 | #include "randnum.h" 2 | #include "ui_randnum.h" 3 | 4 | RandNum::RandNum(QWidget *parent) 5 | : QWidget(parent) 6 | , ui(new Ui::RandNum) 7 | { 8 | ui->setupUi(this); 9 | /* 限制只能输入整数且范围为[1,128 * 1024]*/ 10 | QIntValidator *aIntValidator = new QIntValidator; 11 | aIntValidator->setRange(1, 131072); 12 | ui->lineEditInput->setValidator(aIntValidator); 13 | } 14 | 15 | RandNum::~RandNum() 16 | { 17 | delete ui; 18 | } 19 | 20 | void RandNum::on_pushButtonGen_clicked() 21 | { 22 | QString inputByte = this->ui->lineEditInput->text(); 23 | int randNumByte = inputByte.toInt(); 24 | size_t len = randNumByte * 2 + 1; 25 | std::vector buf; 26 | std::vector str; 27 | 28 | buf.reserve(randNumByte); 29 | 30 | int ret = RAND_bytes((unsigned char *) buf.data(), randNumByte); 31 | 32 | if (ret == 0) { 33 | printTSError(); 34 | } else { 35 | str.reserve(len); 36 | 37 | if (OPENSSL_buf2hexstr_ex(str.data(), 38 | len, 39 | NULL, 40 | (unsigned char *) buf.data(), 41 | randNumByte, 42 | '\0') 43 | != 1) 44 | return; 45 | 46 | this->ui->textBrowserOutput->setText(QString::fromStdString(std::string(str.data(), len))); 47 | } 48 | 49 | return; 50 | } 51 | -------------------------------------------------------------------------------- /randnum.h: -------------------------------------------------------------------------------- 1 | #ifndef RANDNUM_H 2 | #define RANDNUM_H 3 | 4 | #include "tserror.h" 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | namespace Ui { 16 | class RandNum; 17 | } 18 | 19 | class RandNum : public QWidget 20 | { 21 | Q_OBJECT 22 | 23 | public: 24 | explicit RandNum(QWidget *parent = nullptr); 25 | ~RandNum(); 26 | 27 | private slots: 28 | void on_pushButtonGen_clicked(); 29 | 30 | private: 31 | Ui::RandNum *ui; 32 | }; 33 | 34 | #endif // RANDNUM_H 35 | -------------------------------------------------------------------------------- /randnum.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | RandNum 4 | 5 | 6 | 7 | 0 8 | 0 9 | 740 10 | 531 11 | 12 | 13 | 14 | Form 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 生成随机数 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 0 31 | 0 32 | 33 | 34 | 35 | 36 | 10 37 | 10 38 | 39 | 40 | 41 | 128 42 | 43 | 44 | 45 | 46 | 47 | 48 | 字节 49 | 50 | 51 | 52 | 53 | 54 | 55 | Qt::Horizontal 56 | 57 | 58 | 59 | 40 60 | 20 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | Qt::Horizontal 69 | 70 | 71 | 72 | 40 73 | 20 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | Qt::Vertical 82 | 83 | 84 | 85 | 20 86 | 40 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 0 96 | 0 97 | 98 | 99 | 100 | hex格式 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | -------------------------------------------------------------------------------- /sm2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | EVP_PKEY *sm2_key_new_from_raw_pub(const std::string &pub) 5 | { 6 | std::string hex; 7 | std::vector buf; 8 | OSSL_PARAM_BLD *keybld = NULL; 9 | OSSL_PARAM *keyparams = NULL; 10 | EVP_PKEY_CTX *keyctx = NULL; 11 | EVP_PKEY *pkey = NULL; 12 | 13 | hex = std::string("04") + pub; 14 | 15 | keybld = OSSL_PARAM_BLD_new(); 16 | if (keybld == NULL) 17 | goto end; 18 | 19 | buf.reserve(hex.length() / 2); 20 | 21 | if (OPENSSL_hexstr2buf_ex(buf.data(), buf.capacity(), NULL, hex.c_str(), '\0') != 1) 22 | goto end; 23 | 24 | if (!OSSL_PARAM_BLD_push_utf8_string(keybld, OSSL_PKEY_PARAM_GROUP_NAME, "SM2", 3)) 25 | goto end; 26 | 27 | if (!OSSL_PARAM_BLD_push_octet_string(keybld, 28 | OSSL_PKEY_PARAM_PUB_KEY, 29 | buf.data(), 30 | buf.capacity())) 31 | goto end; 32 | 33 | keyparams = OSSL_PARAM_BLD_to_param(keybld); 34 | keyctx = EVP_PKEY_CTX_new_from_name(NULL, "SM2", NULL); 35 | 36 | if (keyctx == NULL || keyparams == NULL) 37 | goto end; 38 | 39 | if (EVP_PKEY_fromdata_init(keyctx) <= 0 40 | || EVP_PKEY_fromdata(keyctx, &pkey, EVP_PKEY_PUBLIC_KEY, keyparams) <= 0) 41 | goto end; 42 | end: 43 | EVP_PKEY_CTX_free(keyctx); 44 | OSSL_PARAM_free(keyparams); 45 | OSSL_PARAM_BLD_free(keybld); 46 | return pkey; 47 | } 48 | 49 | EVP_PKEY *sm2_key_new_from_raw_pub_and_priv(const std::string &pub, const std::string &priv) 50 | { 51 | std::string hex; 52 | std::vector buf; 53 | OSSL_PARAM_BLD *keybld = NULL; 54 | OSSL_PARAM *keyparams = NULL; 55 | EVP_PKEY_CTX *keyctx = NULL; 56 | EVP_PKEY *pkey = NULL; 57 | BIGNUM *bn = NULL; 58 | 59 | keybld = OSSL_PARAM_BLD_new(); 60 | if (keybld == NULL) 61 | goto end; 62 | 63 | if (!OSSL_PARAM_BLD_push_utf8_string(keybld, OSSL_PKEY_PARAM_GROUP_NAME, "SM2", 3)) 64 | goto end; 65 | 66 | buf.clear(); 67 | buf.reserve(priv.length() / 2); 68 | 69 | if (OPENSSL_hexstr2buf_ex(buf.data(), buf.capacity(), NULL, priv.c_str(), '\0') != 1) 70 | goto end; 71 | 72 | bn = BN_new(); 73 | if (bn == NULL) 74 | goto end; 75 | 76 | if (BN_bin2bn(buf.data(), buf.capacity(), bn) == NULL 77 | || !OSSL_PARAM_BLD_push_BN(keybld, OSSL_PKEY_PARAM_PRIV_KEY, bn)) 78 | goto end; 79 | 80 | hex = std::string("04") + pub; 81 | 82 | buf.clear(); 83 | buf.reserve(hex.length() / 2); 84 | 85 | if (OPENSSL_hexstr2buf_ex(buf.data(), buf.capacity(), NULL, hex.c_str(), '\0') != 1) 86 | goto end; 87 | 88 | if (!OSSL_PARAM_BLD_push_octet_string(keybld, 89 | OSSL_PKEY_PARAM_PUB_KEY, 90 | buf.data(), 91 | buf.capacity())) 92 | goto end; 93 | 94 | keyparams = OSSL_PARAM_BLD_to_param(keybld); 95 | keyctx = EVP_PKEY_CTX_new_from_name(NULL, "SM2", NULL); 96 | 97 | if (keyctx == NULL || keyparams == NULL) 98 | goto end; 99 | 100 | if (EVP_PKEY_fromdata_init(keyctx) <= 0 101 | || EVP_PKEY_fromdata(keyctx, &pkey, EVP_PKEY_KEYPAIR, keyparams) <= 0) 102 | goto end; 103 | end: 104 | BN_free(bn); 105 | EVP_PKEY_CTX_free(keyctx); 106 | OSSL_PARAM_free(keyparams); 107 | OSSL_PARAM_BLD_free(keybld); 108 | return pkey; 109 | } 110 | 111 | int sm2_key_get_priv_pem(const EVP_PKEY *pkey, std::string &pem) 112 | { 113 | int ret = 0; 114 | BIO *out = NULL; 115 | long len; 116 | char *buf = NULL; 117 | 118 | out = BIO_new(BIO_s_mem()); 119 | if (out == NULL) 120 | goto end; 121 | 122 | if (!PEM_write_bio_PrivateKey(out, pkey, NULL, NULL, 0, NULL, NULL)) 123 | goto end; 124 | 125 | len = BIO_get_mem_data(out, &buf); 126 | 127 | pem = std::string(buf, len); 128 | 129 | ret = 1; 130 | end: 131 | BIO_free(out); 132 | return ret; 133 | } 134 | 135 | int sm2_key_get_pub_pem(const EVP_PKEY *pkey, std::string &pem) 136 | { 137 | int ret = 0; 138 | BIO *out = NULL; 139 | long len; 140 | char *buf = NULL; 141 | 142 | out = BIO_new(BIO_s_mem()); 143 | if (out == NULL) 144 | goto end; 145 | 146 | if (!PEM_write_bio_PUBKEY(out, pkey)) 147 | goto end; 148 | 149 | len = BIO_get_mem_data(out, &buf); 150 | 151 | pem = std::string(buf, len); 152 | 153 | ret = 1; 154 | end: 155 | BIO_free(out); 156 | return ret; 157 | } 158 | 159 | int sm2_key_get_pub_hex(const EVP_PKEY *pkey, std::string &hex) 160 | { 161 | BIGNUM *qx = NULL, *qy = NULL; 162 | char *pubx = NULL, *puby = NULL; 163 | 164 | if (!EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_EC_PUB_X, &qx) 165 | || !EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_EC_PUB_Y, &qy)) 166 | return 0; 167 | 168 | pubx = BN_bn2hex(qx); 169 | puby = BN_bn2hex(qy); 170 | 171 | hex = std::string(pubx) + std::string(puby); 172 | 173 | BN_clear_free(qx); 174 | BN_clear_free(qy); 175 | OPENSSL_free(pubx); 176 | OPENSSL_free(puby); 177 | 178 | return 1; 179 | } 180 | 181 | int sm2_key_get_priv_hex(const EVP_PKEY *pkey, std::string &hex) 182 | { 183 | BIGNUM *priv = NULL; 184 | char *buf = NULL; 185 | 186 | if (!EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_PRIV_KEY, &priv)) 187 | return 0; 188 | 189 | buf = BN_bn2hex(priv); 190 | 191 | hex = std::string(buf); 192 | 193 | OPENSSL_free(buf); 194 | BN_clear_free(priv); 195 | 196 | return 1; 197 | } 198 | -------------------------------------------------------------------------------- /sm2.h: -------------------------------------------------------------------------------- 1 | #ifndef SM2_H 2 | #define SM2_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | int sm2_key_get_pub_pem(const EVP_PKEY *pkey, std::string &pem); 14 | int sm2_key_get_priv_pem(const EVP_PKEY *pkey, std::string &pem); 15 | int sm2_key_get_pub_hex(const EVP_PKEY *pkey, std::string &hex); 16 | int sm2_key_get_priv_hex(const EVP_PKEY *pkey, std::string &hex); 17 | EVP_PKEY *sm2_key_new_from_raw_pub(const std::string &pub); 18 | EVP_PKEY *sm2_key_new_from_raw_pub_and_priv(const std::string &pub, const std::string &priv); 19 | 20 | #endif // SM2_H 21 | -------------------------------------------------------------------------------- /sm2cert.cpp: -------------------------------------------------------------------------------- 1 | #include "sm2cert.h" 2 | #include "ui_sm2cert.h" 3 | #include 4 | 5 | Sm2Cert::Sm2Cert(QWidget *parent) 6 | : QWidget(parent) 7 | , ui(new Ui::Sm2Cert) 8 | { 9 | ui->setupUi(this); 10 | } 11 | 12 | Sm2Cert::~Sm2Cert() 13 | { 14 | delete ui; 15 | } 16 | 17 | static char *opt_getprog(void) 18 | { 19 | return (char *) ""; 20 | } 21 | 22 | /* 23 | * name is expected to be in the format /type0=value0/type1=value1/type2=... 24 | * where + can be used instead of / to form multi-valued RDNs if canmulti 25 | * and characters may be escaped by \ 26 | */ 27 | static X509_NAME *parse_name(const char *cp, int chtype, int canmulti, const char *desc) 28 | { 29 | int nextismulti = 0; 30 | char *work; 31 | X509_NAME *n; 32 | 33 | if (*cp++ != '/') { 34 | BIO_printf(bio_err, 35 | "%s: %s name is expected to be in the format " 36 | "/type0=value0/type1=value1/type2=... where characters may " 37 | "be escaped by \\. This name is not in that format: '%s'\n", 38 | opt_getprog(), 39 | desc, 40 | --cp); 41 | return NULL; 42 | } 43 | 44 | n = X509_NAME_new(); 45 | if (n == NULL) { 46 | BIO_printf(bio_err, "%s: Out of memory\n", opt_getprog()); 47 | return NULL; 48 | } 49 | work = OPENSSL_strdup(cp); 50 | if (work == NULL) { 51 | BIO_printf(bio_err, "%s: Error copying %s name input\n", opt_getprog(), desc); 52 | goto err; 53 | } 54 | 55 | while (*cp != '\0') { 56 | char *bp = work; 57 | char *typestr = bp; 58 | unsigned char *valstr; 59 | int nid; 60 | int ismulti = nextismulti; 61 | nextismulti = 0; 62 | 63 | /* Collect the type */ 64 | while (*cp != '\0' && *cp != '=') 65 | *bp++ = *cp++; 66 | *bp++ = '\0'; 67 | if (*cp == '\0') { 68 | BIO_printf(bio_err, 69 | "%s: Missing '=' after RDN type string '%s' in %s name string\n", 70 | opt_getprog(), 71 | typestr, 72 | desc); 73 | goto err; 74 | } 75 | ++cp; 76 | 77 | /* Collect the value. */ 78 | valstr = (unsigned char *) bp; 79 | for (; *cp != '\0' && *cp != '/'; *bp++ = *cp++) { 80 | /* unescaped '+' symbol string signals further member of multiRDN */ 81 | if (canmulti && *cp == '+') { 82 | nextismulti = 1; 83 | break; 84 | } 85 | if (*cp == '\\' && *++cp == '\0') { 86 | BIO_printf(bio_err, 87 | "%s: Escape character at end of %s name string\n", 88 | opt_getprog(), 89 | desc); 90 | goto err; 91 | } 92 | } 93 | *bp++ = '\0'; 94 | 95 | /* If not at EOS (must be + or /), move forward. */ 96 | if (*cp != '\0') 97 | ++cp; 98 | 99 | /* Parse */ 100 | nid = OBJ_txt2nid(typestr); 101 | if (nid == NID_undef) { 102 | BIO_printf(bio_err, 103 | "%s: Skipping unknown %s name attribute \"%s\"\n", 104 | opt_getprog(), 105 | desc, 106 | typestr); 107 | if (ismulti) 108 | BIO_printf(bio_err, 109 | "Hint: a '+' in a value string needs be escaped using '\\' else a new " 110 | "member of a multi-valued RDN is expected\n"); 111 | continue; 112 | } 113 | if (*valstr == '\0') { 114 | BIO_printf(bio_err, 115 | "%s: No value provided for %s name attribute \"%s\", skipped\n", 116 | opt_getprog(), 117 | desc, 118 | typestr); 119 | continue; 120 | } 121 | if (!X509_NAME_add_entry_by_NID( 122 | n, nid, chtype, valstr, strlen((char *) valstr), -1, ismulti ? -1 : 0)) { 123 | ERR_print_errors(bio_err); 124 | BIO_printf(bio_err, 125 | "%s: Error adding %s name attribute \"/%s=%s\"\n", 126 | opt_getprog(), 127 | desc, 128 | typestr, 129 | valstr); 130 | goto err; 131 | } 132 | } 133 | 134 | OPENSSL_free(work); 135 | return n; 136 | 137 | err: 138 | X509_NAME_free(n); 139 | OPENSSL_free(work); 140 | return NULL; 141 | } 142 | 143 | static X509 *genCert(int type, 144 | X509 *midCA, 145 | EVP_PKEY *midcaPkey, 146 | QString subj, 147 | QString days, 148 | char **key, 149 | size_t *keylen) 150 | { 151 | X509_NAME *name = NULL; 152 | X509 *userCer = NULL; 153 | std::string str; 154 | long len; 155 | BIO *out = NULL; 156 | X509_EXTENSION *cert_ex = NULL; 157 | X509_REQ *userReq = NULL; 158 | ASN1_INTEGER *aserial = NULL; 159 | const X509_NAME *rootCAname; 160 | time_t curTime; 161 | ASN1_TIME *rootBeforeTime = NULL; 162 | ASN1_TIME *rootAfterTime = NULL; 163 | EVP_PKEY *userKey = EVP_PKEY_Q_keygen(NULL, NULL, "SM2"); 164 | 165 | if (userKey == NULL) { 166 | printTSError(); 167 | return NULL; 168 | } 169 | 170 | out = BIO_new(BIO_s_mem()); 171 | if (out == NULL) 172 | goto end; 173 | 174 | if (!PEM_write_bio_PrivateKey(out, userKey, NULL, NULL, 0, NULL, NULL)) { 175 | printTSError(); 176 | goto end; 177 | } 178 | 179 | len = BIO_get_mem_data(out, NULL); 180 | if (len <= 0) 181 | goto end; 182 | 183 | *key = (char *) malloc(len); 184 | if (*key == NULL) 185 | goto end; 186 | 187 | if (BIO_read(out, *key, len) != len) 188 | goto end; 189 | 190 | *keylen = len; 191 | 192 | userReq = X509_REQ_new(); 193 | if (userReq == NULL) 194 | goto end; 195 | 196 | X509_REQ_set_pubkey(userReq, userKey); 197 | 198 | if (!subj.isEmpty()) { 199 | name = parse_name(subj.toStdString().c_str(), MBSTRING_ASC, 1, "subject"); 200 | 201 | if (!name) { 202 | return NULL; 203 | } 204 | 205 | X509_REQ_set_subject_name(userReq, name); 206 | } 207 | 208 | if (!X509_REQ_set_version(userReq, X509_VERSION_3) 209 | || !X509_REQ_sign(userReq, userKey, EVP_sm3()) || !X509_REQ_verify(userReq, userKey)) 210 | goto end; 211 | 212 | if (type == 0) { 213 | str = "Key Encipherment, Data Encipherment"; 214 | } else { 215 | str = "Digital Signature"; 216 | } 217 | 218 | userCer = X509_new(); 219 | if (userCer == NULL) 220 | goto end; 221 | 222 | cert_ex = X509V3_EXT_conf_nid(NULL, NULL, NID_key_usage, str.c_str()); 223 | if (cert_ex == NULL) 224 | goto end; 225 | 226 | if (!X509_add_ext(userCer, cert_ex, -1) || !X509_set_version(userCer, X509_VERSION_3) 227 | || !X509_set_pubkey(userCer, userKey)) 228 | goto end; 229 | 230 | aserial = ASN1_INTEGER_new(); 231 | 232 | if (!ASN1_INTEGER_set(aserial, 0)) 233 | goto end; 234 | 235 | if (!X509_set_serialNumber(userCer, aserial) || !X509_set_subject_name(userCer, name)) 236 | goto end; 237 | 238 | rootCAname = X509_get_subject_name(midCA); 239 | if (!X509_set_issuer_name(userCer, rootCAname)) 240 | goto end; 241 | 242 | curTime = time(NULL); 243 | rootBeforeTime = ASN1_TIME_new(); 244 | rootAfterTime = ASN1_TIME_adj(NULL, curTime, 0, days.toInt() * 60 * 60 * 24); 245 | 246 | if (!ASN1_TIME_set(rootBeforeTime, curTime) || !X509_set_notBefore(userCer, rootBeforeTime) 247 | || !X509_set_notAfter(userCer, rootAfterTime)) 248 | goto end; 249 | 250 | if (!X509_sign(userCer, midcaPkey, EVP_sm3())) 251 | goto end; 252 | 253 | end: 254 | ASN1_TIME_free(rootAfterTime); 255 | ASN1_TIME_free(rootBeforeTime); 256 | ASN1_INTEGER_free(aserial); 257 | X509_EXTENSION_free(cert_ex); 258 | X509_REQ_free(userReq); 259 | BIO_free(out); 260 | EVP_PKEY_free(userKey); 261 | 262 | return userCer; 263 | } 264 | 265 | void Sm2Cert::on_pushButtonGen_clicked() 266 | { 267 | QString subj = this->ui->lineEditSubj->text(); 268 | QString days = this->ui->lineEditDays->text(); 269 | QFile fsubca(":/certs/subca.pem"); 270 | QFile fpkey(":/certs/subca.key"); 271 | X509 *userSignCer = NULL, *userEncryptCer = NULL; 272 | char *signKey = NULL, *encKey = NULL; 273 | size_t signKeyLen, encKeyLen; 274 | QString subcaQstr, pkeyQstr; 275 | X509 *subca = NULL; 276 | EVP_PKEY *pkey = NULL; 277 | long len; 278 | char *buf = NULL; 279 | BIO *out = NULL; 280 | 281 | if (subj.isEmpty()) { 282 | QMessageBox::warning(NULL, 283 | "warning", 284 | QString("请输入主体名称!"), 285 | QMessageBox::Close, 286 | QMessageBox::Close); 287 | return; 288 | } 289 | 290 | if (days.isEmpty()) { 291 | QMessageBox::warning(NULL, 292 | "warning", 293 | QString("请输入有效期!"), 294 | QMessageBox::Close, 295 | QMessageBox::Close); 296 | return; 297 | } 298 | 299 | if (!fsubca.open(QIODevice::ReadOnly | QIODevice::Text)) { 300 | QMessageBox::warning(NULL, 301 | "warning", 302 | QString("subca.pem打开失败!"), 303 | QMessageBox::Close, 304 | QMessageBox::Close); 305 | return; 306 | } 307 | 308 | if (!fpkey.open(QIODevice::ReadOnly | QIODevice::Text)) { 309 | QMessageBox::warning(NULL, 310 | "warning", 311 | QString("subca.key打开失败!"), 312 | QMessageBox::Close, 313 | QMessageBox::Close); 314 | return; 315 | } 316 | QTextStream subcaInput(&fsubca); 317 | QTextStream pkeyInput(&fpkey); 318 | 319 | subcaQstr = subcaInput.readAll(); 320 | pkeyQstr = pkeyInput.readAll(); 321 | 322 | out = BIO_new(BIO_s_mem()); 323 | if (out == NULL) 324 | goto end; 325 | 326 | if (BIO_write(out, subcaQstr.toStdString().c_str(), subcaQstr.size()) != subcaQstr.size()) 327 | goto end; 328 | 329 | subca = PEM_read_bio_X509(out, NULL, NULL, NULL); 330 | if (subca == NULL) { 331 | this->ui->textBrowserSignKey->setText(subcaQstr); 332 | printTSError(); 333 | goto end; 334 | } 335 | 336 | fsubca.close(); 337 | BIO_reset(out); 338 | 339 | if (BIO_write(out, pkeyQstr.toStdString().c_str(), pkeyQstr.size()) != pkeyQstr.size()) 340 | goto end; 341 | 342 | pkey = PEM_read_bio_PrivateKey(out, NULL, NULL, NULL); 343 | if (pkey == NULL) { 344 | printTSError(); 345 | goto end; 346 | } 347 | 348 | fpkey.close(); 349 | 350 | userSignCer = genCert(1, subca, pkey, subj, days, &signKey, &signKeyLen); 351 | if (userSignCer == NULL) { 352 | printTSError(); 353 | goto end; 354 | } 355 | 356 | userEncryptCer = genCert(0, subca, pkey, subj, days, &encKey, &encKeyLen); 357 | if (userEncryptCer == NULL) { 358 | printTSError(); 359 | goto end; 360 | } 361 | 362 | this->ui->textBrowserSignKey->setText(QString::fromStdString(std::string(signKey, signKeyLen))); 363 | this->ui->textBrowserEncryKey->setText(QString::fromStdString(std::string(encKey, encKeyLen))); 364 | 365 | BIO_reset(out); 366 | 367 | if (!PEM_write_bio_X509(out, userSignCer)) { 368 | printTSError(); 369 | goto end; 370 | } 371 | 372 | len = BIO_get_mem_data(out, &buf); 373 | if (len <= 0) 374 | goto end; 375 | 376 | this->ui->textBrowserSignOutput->setPlainText(QString::fromStdString(std::string(buf, len))); 377 | 378 | BIO_reset(out); 379 | 380 | if (!PEM_write_bio_X509(out, userEncryptCer)) { 381 | printTSError(); 382 | goto end; 383 | } 384 | 385 | len = BIO_get_mem_data(out, &buf); 386 | if (len <= 0) 387 | goto end; 388 | 389 | this->ui->textBrowserEncryptOutput->setPlainText(QString::fromStdString(std::string(buf, len))); 390 | 391 | end: 392 | EVP_PKEY_free(pkey); 393 | X509_free(subca); 394 | BIO_free(out); 395 | free(signKey); 396 | free(encKey); 397 | X509_free(userSignCer); 398 | X509_free(userEncryptCer); 399 | } 400 | -------------------------------------------------------------------------------- /sm2cert.h: -------------------------------------------------------------------------------- 1 | #ifndef SM2CERT_H 2 | #define SM2CERT_H 3 | 4 | #include "tserror.h" 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | namespace Ui { 18 | class Sm2Cert; 19 | } 20 | 21 | class Sm2Cert : public QWidget 22 | { 23 | Q_OBJECT 24 | 25 | public: 26 | explicit Sm2Cert(QWidget *parent = nullptr); 27 | ~Sm2Cert(); 28 | 29 | private slots: 30 | void on_pushButtonGen_clicked(); 31 | 32 | private: 33 | Ui::Sm2Cert *ui; 34 | }; 35 | 36 | #endif // SM2CERT_H 37 | -------------------------------------------------------------------------------- /sm2cert.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | Sm2Cert 4 | 5 | 6 | 7 | 0 8 | 0 9 | 400 10 | 314 11 | 12 | 13 | 14 | Form 15 | 16 | 17 | 18 | 19 | 20 | 21 | 10 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 10 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 0 39 | 40 | 41 | 42 | 43 | 44 | 12 45 | 46 | 47 | 48 | 49 | 50 | 51 | /C=AB/ST=CD/L=EF/O=GH/OU=IJ/CN=test 52 | 53 | 54 | 一般为域名 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 10 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 12 74 | 75 | 76 | 77 | 加密证书&私钥: 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 10 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | Qt::Vertical 94 | 95 | 96 | 97 | 20 98 | 40 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 12 108 | 109 | 110 | 111 | 有效天数: 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 12 120 | 121 | 122 | 123 | 签名证书&私钥: 124 | 125 | 126 | 127 | 128 | 129 | 130 | Qt::Vertical 131 | 132 | 133 | 134 | 20 135 | 40 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 12 145 | 146 | 147 | 148 | 365 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 12 160 | 161 | 162 | 163 | 主体名称: 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 12 172 | 173 | 174 | 175 | 生成证书 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | -------------------------------------------------------------------------------- /sm2encrypt.cpp: -------------------------------------------------------------------------------- 1 | #include "sm2encrypt.h" 2 | #include "sm2.h" 3 | #include "ui_sm2encrypt.h" 4 | 5 | Sm2Encrypt::Sm2Encrypt(QWidget *parent) 6 | : QWidget(parent) 7 | , ui(new Ui::Sm2Encrypt) 8 | { 9 | ui->setupUi(this); 10 | } 11 | 12 | Sm2Encrypt::~Sm2Encrypt() 13 | { 14 | delete ui; 15 | } 16 | 17 | void Sm2Encrypt::on_pushButtonEncrypt_clicked() 18 | { 19 | QString input = this->ui->textEditPlain->toPlainText(); 20 | QString pubQstrInput = this->ui->plainTextEditPub->toPlainText(); 21 | EVP_PKEY_CTX *encctx = NULL; 22 | EVP_PKEY *pkey = NULL; 23 | size_t outlen; 24 | std::vector buf; 25 | std::vector str; 26 | 27 | if (pubQstrInput.isEmpty()) { 28 | QMessageBox::warning(NULL, 29 | "warning", 30 | QString("请输入公钥!"), 31 | QMessageBox::Close, 32 | QMessageBox::Close); 33 | return; 34 | } 35 | 36 | if (input.isEmpty()) { 37 | QMessageBox::warning(NULL, 38 | "warning", 39 | QString("请输入明文!"), 40 | QMessageBox::Close, 41 | QMessageBox::Close); 42 | return; 43 | } 44 | 45 | pkey = sm2_key_new_from_raw_pub(pubQstrInput.toStdString()); 46 | if (pkey == NULL) { 47 | printTSError(); 48 | goto end; 49 | } 50 | 51 | encctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL); 52 | if (encctx == NULL) 53 | goto end; 54 | 55 | if (EVP_PKEY_encrypt_init(encctx) <= 0 56 | || EVP_PKEY_encrypt(encctx, 57 | NULL, 58 | &outlen, 59 | (const unsigned char *) input.toStdString().c_str(), 60 | input.toStdString().length()) 61 | <= 0) 62 | goto end; 63 | 64 | buf.clear(); 65 | buf.reserve(outlen); 66 | 67 | if (EVP_PKEY_encrypt(encctx, 68 | buf.data(), 69 | &outlen, 70 | (const unsigned char *) input.toStdString().c_str(), 71 | input.toStdString().length()) 72 | <= 0) 73 | goto end; 74 | 75 | str.reserve(outlen * 2 + 1); 76 | if (OPENSSL_buf2hexstr_ex(str.data(), str.capacity(), NULL, buf.data(), outlen, '\0') != 1) { 77 | printTSError(); 78 | goto end; 79 | } 80 | 81 | this->ui->textEditCipher->setText(QString::fromStdString(std::string(str.data(), outlen * 2))); 82 | 83 | end: 84 | EVP_PKEY_free(pkey); 85 | } 86 | 87 | void Sm2Encrypt::on_pushButtonDecrypt_clicked() 88 | { 89 | QString input = this->ui->textEditCipher->toPlainText(); 90 | QString pubQstrInput = this->ui->plainTextEditPub->toPlainText(); 91 | QString privQstrInput = this->ui->plainTextEditPriv->toPlainText(); 92 | EVP_PKEY_CTX *encctx = NULL; 93 | EVP_PKEY *pkey = NULL; 94 | size_t outlen; 95 | std::vector buf; 96 | std::vector str; 97 | 98 | if (pubQstrInput.isEmpty() || privQstrInput.isEmpty()) { 99 | QMessageBox::warning(NULL, 100 | "warning", 101 | QString("请输入公钥和私钥!"), 102 | QMessageBox::Close, 103 | QMessageBox::Close); 104 | return; 105 | } 106 | 107 | if (input.isEmpty()) { 108 | QMessageBox::warning(NULL, 109 | "warning", 110 | QString("请输入密文!"), 111 | QMessageBox::Close, 112 | QMessageBox::Close); 113 | return; 114 | } 115 | 116 | pkey = sm2_key_new_from_raw_pub_and_priv(pubQstrInput.toStdString(), 117 | privQstrInput.toStdString()); 118 | if (pkey == NULL) { 119 | printTSError(); 120 | goto end; 121 | } 122 | 123 | encctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL); 124 | if (encctx == NULL) 125 | goto end; 126 | 127 | buf.clear(); 128 | buf.reserve(input.length() / 2); 129 | 130 | if (OPENSSL_hexstr2buf_ex(buf.data(), buf.capacity(), NULL, input.toStdString().c_str(), '\0') 131 | != 1) { 132 | printTSError(); 133 | goto end; 134 | } 135 | 136 | if (EVP_PKEY_decrypt_init(encctx) <= 0 137 | || EVP_PKEY_decrypt(encctx, NULL, &outlen, buf.data(), buf.capacity()) <= 0) 138 | goto end; 139 | 140 | str.clear(); 141 | str.reserve(outlen); 142 | 143 | if (EVP_PKEY_decrypt(encctx, (unsigned char *) str.data(), &outlen, buf.data(), buf.capacity()) 144 | <= 0) 145 | goto end; 146 | 147 | this->ui->textEditPlain->setText(QString::fromStdString(std::string(str.data(), outlen))); 148 | 149 | end: 150 | EVP_PKEY_free(pkey); 151 | } 152 | 153 | void Sm2Encrypt::on_pushButtonGen_clicked() 154 | { 155 | EVP_PKEY *pkey = NULL; 156 | std::string hex; 157 | 158 | pkey = EVP_PKEY_Q_keygen(NULL, NULL, "SM2"); 159 | if (pkey == NULL) { 160 | printTSError(); 161 | goto end; 162 | } 163 | 164 | if (!sm2_key_get_pub_hex(pkey, hex)) { 165 | printTSError(); 166 | goto end; 167 | } 168 | 169 | this->ui->plainTextEditPub->setPlainText(QString::fromStdString(hex)); 170 | 171 | if (!sm2_key_get_priv_hex(pkey, hex)) { 172 | printTSError(); 173 | goto end; 174 | } 175 | 176 | this->ui->plainTextEditPriv->setPlainText(QString::fromStdString(hex)); 177 | 178 | end: 179 | EVP_PKEY_free(pkey); 180 | return; 181 | } 182 | -------------------------------------------------------------------------------- /sm2encrypt.h: -------------------------------------------------------------------------------- 1 | #ifndef SM2ENCRYPT_H 2 | #define SM2ENCRYPT_H 3 | 4 | #include "tserror.h" 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | namespace Ui { 17 | class Sm2Encrypt; 18 | } 19 | 20 | class Sm2Encrypt : public QWidget 21 | { 22 | Q_OBJECT 23 | 24 | public: 25 | explicit Sm2Encrypt(QWidget *parent = nullptr); 26 | ~Sm2Encrypt(); 27 | 28 | private slots: 29 | void on_pushButtonEncrypt_clicked(); 30 | 31 | void on_pushButtonDecrypt_clicked(); 32 | 33 | void on_pushButtonGen_clicked(); 34 | 35 | private: 36 | Ui::Sm2Encrypt *ui; 37 | }; 38 | 39 | #endif // SM2ENCRYPT_H 40 | -------------------------------------------------------------------------------- /sm2encrypt.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | Sm2Encrypt 4 | 5 | 6 | 7 | 0 8 | 0 9 | 436 10 | 412 11 | 12 | 13 | 14 | Form 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | hex格式 23 | 24 | 25 | 26 | 27 | 28 | 29 | 私钥 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 密文 40 | 41 | 42 | 43 | 44 | 45 | 46 | 明文 47 | 48 | 49 | 50 | 51 | 52 | 53 | hex格式 54 | 55 | 56 | 57 | 58 | 59 | 60 | 公钥 61 | 62 | 63 | 64 | 65 | 66 | 67 | hex格式 68 | 69 | 70 | 71 | 72 | 73 | 74 | 公钥加密 75 | 76 | 77 | 78 | 79 | 80 | 81 | 私钥解密 82 | 83 | 84 | 85 | 86 | 87 | 88 | 生成密钥对 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /sm2key.cpp: -------------------------------------------------------------------------------- 1 | #include "sm2key.h" 2 | #include "sm2.h" 3 | #include "ui_sm2key.h" 4 | 5 | Sm2Key::Sm2Key(QWidget *parent) 6 | : QWidget(parent) 7 | , ui(new Ui::Sm2Key) 8 | { 9 | ui->setupUi(this); 10 | } 11 | 12 | Sm2Key::~Sm2Key() 13 | { 14 | delete ui; 15 | } 16 | 17 | void Sm2Key::on_pushButtonGen_clicked() 18 | { 19 | EVP_PKEY *pkey = NULL; 20 | std::string pem, hex; 21 | 22 | pkey = EVP_PKEY_Q_keygen(NULL, NULL, "SM2"); 23 | if (pkey == NULL) { 24 | printTSError(); 25 | goto end; 26 | } 27 | 28 | if (!sm2_key_get_priv_pem(pkey, pem)) { 29 | printTSError(); 30 | goto end; 31 | } 32 | 33 | this->ui->textBrowserPrivPem->setText(QString::fromStdString(pem)); 34 | 35 | if (!sm2_key_get_pub_pem(pkey, pem)) { 36 | printTSError(); 37 | goto end; 38 | } 39 | 40 | this->ui->textBrowserPubPem->setText(QString::fromStdString(pem)); 41 | 42 | if (!sm2_key_get_pub_hex(pkey, hex)) { 43 | printTSError(); 44 | goto end; 45 | } 46 | 47 | this->ui->textBrowserPubkey->setText(QString::fromStdString(hex)); 48 | 49 | if (!sm2_key_get_priv_hex(pkey, hex)) { 50 | printTSError(); 51 | goto end; 52 | } 53 | 54 | this->ui->textBrowserPrivkey->setText(QString::fromStdString(hex)); 55 | 56 | end: 57 | EVP_PKEY_free(pkey); 58 | return; 59 | } 60 | -------------------------------------------------------------------------------- /sm2key.h: -------------------------------------------------------------------------------- 1 | #ifndef SM2KEY_H 2 | #define SM2KEY_H 3 | 4 | #include "tserror.h" 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | namespace Ui { 18 | class Sm2Key; 19 | } 20 | 21 | class Sm2Key : public QWidget 22 | { 23 | Q_OBJECT 24 | 25 | public: 26 | explicit Sm2Key(QWidget *parent = nullptr); 27 | ~Sm2Key(); 28 | 29 | private slots: 30 | void on_pushButtonGen_clicked(); 31 | 32 | private: 33 | Ui::Sm2Key *ui; 34 | }; 35 | 36 | #endif // SM2KEY_H 37 | -------------------------------------------------------------------------------- /sm2key.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | Sm2Key 4 | 5 | 6 | 7 | 0 8 | 0 9 | 573 10 | 503 11 | 12 | 13 | 14 | Form 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | SM2私钥(PEM) 29 | 30 | 31 | 32 | 33 | 34 | 35 | SM2私钥 36 | 37 | 38 | 39 | 40 | 41 | 42 | SM2公钥(x||y) 43 | 44 | 45 | 46 | 47 | 48 | 49 | 生成密钥对 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | SM2公钥(PEM) 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /sm2signverify.cpp: -------------------------------------------------------------------------------- 1 | #include "sm2signverify.h" 2 | #include "sm2.h" 3 | #include "ui_sm2signverify.h" 4 | 5 | Sm2SignVerify::Sm2SignVerify(QWidget *parent) 6 | : QWidget(parent) 7 | , ui(new Ui::Sm2SignVerify) 8 | { 9 | ui->setupUi(this); 10 | } 11 | 12 | Sm2SignVerify::~Sm2SignVerify() 13 | { 14 | delete ui; 15 | } 16 | 17 | void Sm2SignVerify::on_pushButtonGenKey_clicked() 18 | { 19 | EVP_PKEY *pkey = NULL; 20 | std::string hex; 21 | 22 | pkey = EVP_PKEY_Q_keygen(NULL, NULL, "SM2"); 23 | if (pkey == NULL) { 24 | printTSError(); 25 | goto end; 26 | } 27 | 28 | if (!sm2_key_get_pub_hex(pkey, hex)) { 29 | printTSError(); 30 | goto end; 31 | } 32 | 33 | this->ui->plainTextEditPubKey->setPlainText(QString::fromStdString(hex)); 34 | 35 | if (!sm2_key_get_priv_hex(pkey, hex)) { 36 | printTSError(); 37 | goto end; 38 | } 39 | 40 | this->ui->lineEditPriKey->setText(QString::fromStdString(hex)); 41 | 42 | end: 43 | EVP_PKEY_free(pkey); 44 | return; 45 | } 46 | 47 | void Sm2SignVerify::on_pushButtonSign_clicked() 48 | { 49 | /* 获取私钥 */ 50 | QString pubQstr = this->ui->plainTextEditPubKey->toPlainText(); 51 | QString priQstr = this->ui->lineEditPriKey->text(); 52 | QString inputQstr = this->ui->textEditData->toPlainText(); 53 | EVP_PKEY *pkey = NULL; 54 | EVP_MD_CTX *mctx = NULL; 55 | size_t siglen = 0; 56 | std::vector sig; 57 | std::vector str; 58 | 59 | if (priQstr.isEmpty()) { 60 | QMessageBox::warning(NULL, 61 | "warning", 62 | QString("请输入或生成私钥!"), 63 | QMessageBox::Close, 64 | QMessageBox::Close); 65 | return; 66 | } 67 | 68 | if (inputQstr.isEmpty()) { 69 | QMessageBox::warning(NULL, 70 | "warning", 71 | QString("请输入待签名数据!"), 72 | QMessageBox::Close, 73 | QMessageBox::Close); 74 | return; 75 | } 76 | 77 | pkey = sm2_key_new_from_raw_pub_and_priv(pubQstr.toStdString(), priQstr.toStdString()); 78 | if (pkey == NULL) { 79 | printTSError(); 80 | return; 81 | } 82 | 83 | mctx = EVP_MD_CTX_new(); 84 | if (mctx == NULL) 85 | goto end; 86 | 87 | if (!EVP_DigestSignInit(mctx, NULL, EVP_sm3(), NULL, pkey) 88 | || !EVP_DigestSign(mctx, 89 | NULL, 90 | &siglen, 91 | (unsigned char *) inputQstr.toStdString().c_str(), 92 | inputQstr.size())) { 93 | printTSError(); 94 | goto end; 95 | } 96 | 97 | sig.reserve(siglen); 98 | 99 | if (EVP_DigestSign(mctx, 100 | sig.data(), 101 | &siglen, 102 | (unsigned char *) inputQstr.toStdString().c_str(), 103 | inputQstr.size()) 104 | != 1) { 105 | printTSError(); 106 | goto end; 107 | } 108 | 109 | str.reserve(siglen * 2 + 1); 110 | 111 | if (OPENSSL_buf2hexstr_ex(str.data(), str.capacity(), NULL, sig.data(), siglen, '\0') != 1) { 112 | printTSError(); 113 | goto end; 114 | } 115 | 116 | this->ui->plainTextEditSign->setPlainText( 117 | QString::fromStdString(std::string(str.data(), str.capacity()))); 118 | end: 119 | EVP_MD_CTX_free(mctx); 120 | EVP_PKEY_free(pkey); 121 | return; 122 | } 123 | 124 | void Sm2SignVerify::on_pushButtonVerify_clicked() 125 | { 126 | QString pubQstrInput = this->ui->plainTextEditPubKey->toPlainText(); 127 | QString inputQstr = this->ui->textEditData->toPlainText(); 128 | QString signQstr = this->ui->plainTextEditSign->toPlainText(); 129 | std::vector sig; 130 | EVP_PKEY *pkey = NULL; 131 | EVP_MD_CTX *mctx = NULL; 132 | int ret; 133 | 134 | if (pubQstrInput.isEmpty()) { 135 | QMessageBox::warning(NULL, 136 | "warning", 137 | QString("请输入公钥!"), 138 | QMessageBox::Close, 139 | QMessageBox::Close); 140 | return; 141 | } 142 | 143 | if (signQstr.isEmpty()) { 144 | QMessageBox::warning(NULL, 145 | "warning", 146 | QString("请输入签名!"), 147 | QMessageBox::Close, 148 | QMessageBox::Close); 149 | return; 150 | } 151 | 152 | sig.reserve(signQstr.size() / 2); 153 | 154 | if (OPENSSL_hexstr2buf_ex(sig.data(), sig.capacity(), NULL, signQstr.toStdString().c_str(), '\0') 155 | != 1) { 156 | printTSError(); 157 | goto end; 158 | } 159 | 160 | pkey = sm2_key_new_from_raw_pub(pubQstrInput.toStdString()); 161 | if (pkey == NULL) { 162 | printTSError(); 163 | goto end; 164 | } 165 | 166 | mctx = EVP_MD_CTX_new(); 167 | if (mctx == NULL) 168 | goto end; 169 | 170 | if (!EVP_DigestVerifyInit(mctx, NULL, EVP_sm3(), NULL, pkey)) { 171 | printTSError(); 172 | goto end; 173 | } 174 | /* 验签 */ 175 | ret = EVP_DigestVerify(mctx, 176 | sig.data(), 177 | sig.capacity(), 178 | (unsigned char *) inputQstr.toStdString().c_str(), 179 | inputQstr.size()); 180 | if (ret == 1) { 181 | QMessageBox::information(NULL, 182 | "success", 183 | QString("验签成功!"), 184 | QMessageBox::Close, 185 | QMessageBox::Close); 186 | } else if (ret == 0) { 187 | QMessageBox::warning(NULL, 188 | "failed", 189 | QString("验签失败!"), 190 | QMessageBox::Close, 191 | QMessageBox::Close); 192 | } else { 193 | getError(); 194 | return; 195 | } 196 | end: 197 | EVP_MD_CTX_free(mctx); 198 | EVP_PKEY_free(pkey); 199 | return; 200 | } 201 | -------------------------------------------------------------------------------- /sm2signverify.h: -------------------------------------------------------------------------------- 1 | #ifndef SM2SIGNVERIFY_H 2 | #define SM2SIGNVERIFY_H 3 | 4 | #include "tserror.h" 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | namespace Ui { 12 | class Sm2SignVerify; 13 | } 14 | 15 | class Sm2SignVerify : public QWidget 16 | { 17 | Q_OBJECT 18 | 19 | public: 20 | explicit Sm2SignVerify(QWidget *parent = nullptr); 21 | ~Sm2SignVerify(); 22 | 23 | private slots: 24 | void on_pushButtonGenKey_clicked(); 25 | 26 | void on_pushButtonSign_clicked(); 27 | 28 | void on_pushButtonVerify_clicked(); 29 | 30 | private: 31 | Ui::Sm2SignVerify *ui; 32 | }; 33 | 34 | #endif // SM2SIGNVERIFY_H 35 | -------------------------------------------------------------------------------- /sm2signverify.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | Sm2SignVerify 4 | 5 | 6 | 7 | 0 8 | 0 9 | 390 10 | 318 11 | 12 | 13 | 14 | Form 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 12 24 | 25 | 26 | 27 | 待签名/验签数据: 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 12 36 | 37 | 38 | 39 | 生成密钥对 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 12 48 | 49 | 50 | 51 | 私钥: 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 12 60 | 61 | 62 | 63 | hex格式 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 12 72 | 73 | 74 | 75 | 公钥: 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 12 84 | 85 | 86 | 87 | hex格式 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 12 96 | 97 | 98 | 99 | 签名: 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 12 108 | 109 | 110 | 111 | 生成签名 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 12 120 | 121 | 122 | 123 | 验证签名 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | hex格式 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | -------------------------------------------------------------------------------- /sm3hash.cpp: -------------------------------------------------------------------------------- 1 | #include "sm3hash.h" 2 | #include "ui_sm3hash.h" 3 | 4 | Sm3Hash::Sm3Hash(QWidget *parent) 5 | : QWidget(parent) 6 | , ui(new Ui::Sm3Hash) 7 | { 8 | ui->setupUi(this); 9 | } 10 | 11 | Sm3Hash::~Sm3Hash() 12 | { 13 | delete ui; 14 | } 15 | 16 | void Sm3Hash::on_pushButtonGen_clicked() 17 | { 18 | QString input = this->ui->plainTextEditInput->toPlainText(); 19 | unsigned char md[32] = {}; 20 | unsigned char hex[65]; 21 | size_t mdlen = 0; 22 | 23 | if (input.isEmpty()) { 24 | if (input.isEmpty()) { 25 | QMessageBox::warning(NULL, 26 | "warning", 27 | QString("请输入数据!"), 28 | QMessageBox::Close, 29 | QMessageBox::Close); 30 | return; 31 | } 32 | } 33 | 34 | if (!EVP_Q_digest(NULL, "SM3", NULL, input.toStdString().c_str(), input.size(), md, &mdlen)) { 35 | printTSError(); 36 | return; 37 | } 38 | 39 | if (OPENSSL_buf2hexstr_ex((char *) hex, sizeof(hex), NULL, md, mdlen, '\0') != 1) { 40 | printTSError(); 41 | return; 42 | } 43 | 44 | this->ui->textBrowserOutput->setText( 45 | QString::fromStdString(std::string((char *) hex, sizeof(hex)))); 46 | } 47 | -------------------------------------------------------------------------------- /sm3hash.h: -------------------------------------------------------------------------------- 1 | #ifndef SM3HASH_H 2 | #define SM3HASH_H 3 | 4 | #include "tserror.h" 5 | #include 6 | #include 7 | #include 8 | 9 | namespace Ui { 10 | class Sm3Hash; 11 | } 12 | 13 | class Sm3Hash : public QWidget 14 | { 15 | Q_OBJECT 16 | 17 | public: 18 | explicit Sm3Hash(QWidget *parent = nullptr); 19 | ~Sm3Hash(); 20 | 21 | private slots: 22 | void on_pushButtonGen_clicked(); 23 | 24 | private: 25 | Ui::Sm3Hash *ui; 26 | }; 27 | 28 | #endif // SM3HASH_H 29 | -------------------------------------------------------------------------------- /sm3hash.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | Sm3Hash 4 | 5 | 6 | 7 | 0 8 | 0 9 | 400 10 | 300 11 | 12 | 13 | 14 | Form 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 12 24 | 25 | 26 | 27 | 输入内容: 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 12 36 | 37 | 38 | 39 | hex格式 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 12 48 | 49 | 50 | 51 | hello SM3 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 12 60 | 61 | 62 | 63 | 杂凑结果: 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 12 72 | 73 | 74 | 75 | 生成 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /sm4encrypt.cpp: -------------------------------------------------------------------------------- 1 | #include "sm4encrypt.h" 2 | #include "ui_sm4encrypt.h" 3 | #include 4 | 5 | Sm4encrypt::Sm4encrypt(QWidget *parent) 6 | : QWidget(parent) 7 | , ui(new Ui::Sm4encrypt) 8 | { 9 | ui->setupUi(this); 10 | } 11 | 12 | Sm4encrypt::~Sm4encrypt() 13 | { 14 | delete ui; 15 | } 16 | 17 | static int do_sm4_crypt(const char *algo, 18 | int enc, 19 | const unsigned char *key, 20 | const unsigned char *iv, 21 | const unsigned char *input, 22 | size_t inlen, 23 | unsigned char *output, 24 | size_t *outlen) 25 | { 26 | int ret = 0; 27 | EVP_CIPHER_CTX *ctx = NULL; 28 | EVP_CIPHER *cipher = NULL; 29 | int len, lenf; 30 | 31 | ctx = EVP_CIPHER_CTX_new(); 32 | if (ctx == NULL) 33 | goto end; 34 | 35 | cipher = EVP_CIPHER_fetch(NULL, algo, NULL); 36 | if (cipher == NULL) 37 | goto end; 38 | 39 | if (!EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, enc)) 40 | goto end; 41 | 42 | if (!EVP_CipherUpdate(ctx, output, &len, input, inlen)) 43 | goto end; 44 | 45 | if (!EVP_CipherFinal_ex(ctx, output + len, &lenf)) 46 | goto end; 47 | 48 | *outlen = len + lenf; 49 | ret = 1; 50 | end: 51 | EVP_CIPHER_CTX_free(ctx); 52 | return ret; 53 | } 54 | 55 | void Sm4encrypt::on_pushButtonEncrypt_clicked() 56 | { 57 | QString algo = this->ui->comboBoxMode->currentText(); 58 | QString keyQstr = this->ui->lineEditKey->text(); 59 | QString ivQstr = this->ui->lineEditIV->text(); 60 | QString inputQstr = this->ui->plainTextEditPlain->toPlainText(); 61 | std::vector key, iv, outbuf; 62 | std::vector outhex; 63 | size_t outlen; 64 | 65 | if (keyQstr.isEmpty()) { 66 | QMessageBox::warning(NULL, 67 | "warning", 68 | QString("请输入密钥!"), 69 | QMessageBox::Close, 70 | QMessageBox::Close); 71 | return; 72 | } 73 | 74 | if (algo != "SM4-ECB" && ivQstr.isEmpty()) { 75 | QMessageBox::warning(NULL, 76 | "warning", 77 | QString("请输入初始化向量IV!"), 78 | QMessageBox::Close, 79 | QMessageBox::Close); 80 | return; 81 | } 82 | 83 | key.reserve(keyQstr.size() / 2); 84 | 85 | if (OPENSSL_hexstr2buf_ex(key.data(), key.capacity(), NULL, keyQstr.toStdString().c_str(), '\0') 86 | != 1) { 87 | printTSError(); 88 | return; 89 | } 90 | 91 | iv.reserve(ivQstr.size() / 2); 92 | 93 | if (OPENSSL_hexstr2buf_ex(iv.data(), iv.capacity(), NULL, ivQstr.toStdString().c_str(), '\0') 94 | != 1) { 95 | printTSError(); 96 | return; 97 | } 98 | 99 | outbuf.reserve(inputQstr.size() + 16); 100 | 101 | if (do_sm4_crypt(algo.toStdString().c_str(), 102 | 1, 103 | key.data(), 104 | iv.data(), 105 | (const unsigned char *) inputQstr.toStdString().c_str(), 106 | inputQstr.size(), 107 | outbuf.data(), 108 | &outlen) 109 | != 1) { 110 | printTSError(); 111 | return; 112 | } 113 | 114 | outhex.reserve(outlen * 2 + 1); 115 | 116 | if (OPENSSL_buf2hexstr_ex(outhex.data(), outhex.capacity(), NULL, outbuf.data(), outlen, '\0') 117 | != 1) { 118 | printTSError(); 119 | return; 120 | } 121 | 122 | this->ui->plainTextEditCipher->setPlainText(QString(outhex.data())); 123 | } 124 | 125 | void Sm4encrypt::on_pushButtonDecrypt_clicked() 126 | { 127 | QString algo = this->ui->comboBoxMode->currentText(); 128 | QString keyQstr = this->ui->lineEditKey->text(); 129 | QString ivQstr = this->ui->lineEditIV->text(); 130 | QString inputQstr = this->ui->plainTextEditCipher->toPlainText(); 131 | std::vector key, iv, input; 132 | std::vector outbuf; 133 | size_t outlen; 134 | 135 | if (keyQstr.isEmpty()) { 136 | QMessageBox::warning(NULL, 137 | "warning", 138 | QString("请输入密钥!"), 139 | QMessageBox::Close, 140 | QMessageBox::Close); 141 | return; 142 | } 143 | 144 | if (algo != "SM4-ECB" && ivQstr.isEmpty()) { 145 | QMessageBox::warning(NULL, 146 | "warning", 147 | QString("请输入初始化向量IV!"), 148 | QMessageBox::Close, 149 | QMessageBox::Close); 150 | return; 151 | } 152 | 153 | key.reserve(keyQstr.size() / 2); 154 | 155 | if (OPENSSL_hexstr2buf_ex(key.data(), key.capacity(), NULL, keyQstr.toStdString().c_str(), '\0') 156 | != 1) { 157 | printTSError(); 158 | return; 159 | } 160 | 161 | iv.reserve(ivQstr.size() / 2); 162 | 163 | if (OPENSSL_hexstr2buf_ex(iv.data(), iv.capacity(), NULL, ivQstr.toStdString().c_str(), '\0') 164 | != 1) { 165 | printTSError(); 166 | return; 167 | } 168 | 169 | input.reserve(inputQstr.size() / 2); 170 | if (OPENSSL_hexstr2buf_ex(input.data(), 171 | input.capacity(), 172 | NULL, 173 | inputQstr.toStdString().c_str(), 174 | '\0') 175 | != 1) { 176 | printTSError(); 177 | return; 178 | } 179 | 180 | outbuf.reserve(input.capacity()); 181 | 182 | if (do_sm4_crypt(algo.toStdString().c_str(), 183 | 0, 184 | key.data(), 185 | iv.data(), 186 | input.data(), 187 | input.capacity(), 188 | (unsigned char *) outbuf.data(), 189 | &outlen) 190 | != 1) { 191 | printTSError(); 192 | return; 193 | } 194 | 195 | this->ui->plainTextEditPlain->setPlainText( 196 | QString::fromStdString(std::string(outbuf.data(), outlen))); 197 | } 198 | 199 | void Sm4encrypt::on_pushButtonRandomIV_clicked() 200 | { 201 | unsigned char buf[16]; 202 | std::vector hex; 203 | 204 | if (RAND_bytes(buf, sizeof(buf)) != 1) { 205 | printTSError(); 206 | return; 207 | } 208 | 209 | hex.reserve(sizeof(buf) * 2 + 1); 210 | 211 | if (OPENSSL_buf2hexstr_ex(hex.data(), hex.capacity(), NULL, buf, sizeof(buf), '\0') != 1) { 212 | printTSError(); 213 | return; 214 | } 215 | 216 | this->ui->lineEditIV->setText(hex.data()); 217 | } 218 | 219 | void Sm4encrypt::on_pushButtonRandomKey_clicked() 220 | { 221 | unsigned char buf[16]; 222 | std::vector hex; 223 | 224 | if (RAND_bytes(buf, sizeof(buf)) != 1) { 225 | printTSError(); 226 | return; 227 | } 228 | 229 | hex.reserve(sizeof(buf) * 2 + 1); 230 | 231 | if (OPENSSL_buf2hexstr_ex(hex.data(), hex.capacity(), NULL, buf, sizeof(buf), '\0') != 1) { 232 | printTSError(); 233 | return; 234 | } 235 | 236 | this->ui->lineEditKey->setText(hex.data()); 237 | } 238 | 239 | void Sm4encrypt::on_comboBoxMode_currentTextChanged(const QString &arg1) 240 | { 241 | if (arg1 == "SM4-ECB") { 242 | this->ui->lineEditIV->setEnabled(false); 243 | this->ui->lineEditIV->hide(); 244 | } else { 245 | this->ui->lineEditIV->setEnabled(true); 246 | this->ui->lineEditIV->show(); 247 | } 248 | } 249 | -------------------------------------------------------------------------------- /sm4encrypt.h: -------------------------------------------------------------------------------- 1 | #ifndef SM4ENCRYPT_H 2 | #define SM4ENCRYPT_H 3 | 4 | #include "tserror.h" 5 | #include 6 | #include 7 | #include 8 | namespace Ui { 9 | class Sm4encrypt; 10 | } 11 | 12 | class Sm4encrypt : public QWidget 13 | { 14 | Q_OBJECT 15 | 16 | public: 17 | explicit Sm4encrypt(QWidget *parent = nullptr); 18 | ~Sm4encrypt(); 19 | 20 | private slots: 21 | void on_pushButtonEncrypt_clicked(); 22 | 23 | void on_pushButtonDecrypt_clicked(); 24 | 25 | void on_pushButtonRandomIV_clicked(); 26 | 27 | void on_pushButtonRandomKey_clicked(); 28 | 29 | void on_comboBoxMode_currentTextChanged(const QString &arg1); 30 | 31 | private: 32 | Ui::Sm4encrypt *ui; 33 | }; 34 | 35 | #endif // SM4ENCRYPT_H 36 | -------------------------------------------------------------------------------- /sm4encrypt.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | Sm4encrypt 4 | 5 | 6 | 7 | 0 8 | 0 9 | 400 10 | 329 11 | 12 | 13 | 14 | Form 15 | 16 | 17 | 18 | 19 | 20 | 21 | 12 22 | 23 | 24 | 25 | 26 | SM4-CBC 27 | 28 | 29 | 30 | 31 | SM4-ECB 32 | 33 | 34 | 35 | 36 | SM4-CFB 37 | 38 | 39 | 40 | 41 | SM4-OFB 42 | 43 | 44 | 45 | 46 | SM4-CTR 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 12 56 | 57 | 58 | 59 | 明文: 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 12 68 | 69 | 70 | 71 | hello tongsuo 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 12 80 | 81 | 82 | 83 | 加密模式: 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 12 92 | 93 | 94 | 95 | 96 | 97 | 98 | hex格式 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 12 107 | 108 | 109 | 110 | 初始化向量: 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 12 119 | 120 | 121 | 122 | 密文: 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 12 133 | 134 | 135 | 136 | 解密 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | Qt::Vertical 149 | 150 | 151 | 152 | 20 153 | 40 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 12 163 | 164 | 165 | 166 | 密钥: 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 12 175 | 176 | 177 | 178 | 179 | 180 | 181 | hex格式 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 12 190 | 191 | 192 | 193 | 加密 194 | 195 | 196 | 197 | 198 | 199 | 200 | hex格式 201 | 202 | 203 | 204 | 205 | 206 | 207 | 随机 208 | 209 | 210 | 211 | 212 | 213 | 214 | 随机 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | -------------------------------------------------------------------------------- /tlcpclient.cpp: -------------------------------------------------------------------------------- 1 | #include "tlcpclient.h" 2 | #include "ui_tlcpclient.h" 3 | 4 | TLCPclient::TLCPclient(QWidget *parent) 5 | : QWidget(parent) 6 | , ui(new Ui::TLCPclient) 7 | { 8 | ui->setupUi(this); 9 | ui->pushButtonSend->setEnabled(false); 10 | } 11 | 12 | TLCPclient::~TLCPclient() 13 | { 14 | delete ui; 15 | SSL_free(ssl); 16 | ssl = NULL; 17 | SSL_CTX_free(ctx); 18 | ctx = NULL; 19 | socket.close(); 20 | } 21 | 22 | void TLCPclient::on_pushButtonConnect_clicked() 23 | { 24 | int ret, err; 25 | 26 | if (ui->pushButtonConnect->text() == "连接服务器") { 27 | //获取域名端口 28 | QString addrQstr = this->ui->lineEditAddr->text(); 29 | QString portQstr = this->ui->lineEditPort->text(); 30 | QString cipherList = this->ui->lineEditCiphers->text(); 31 | // 创建一个 QSslSocket对象设置地址并连接 32 | 33 | this->socket.reset(); 34 | this->socket.connectToHost(addrQstr, portQstr.toInt()); 35 | if (!this->socket.waitForConnected()) { 36 | QMessageBox::warning(NULL, 37 | "connect failed", 38 | QString("TCP连接失败,请确认服务器地址&端口号是否正确"), 39 | QMessageBox::Ok, 40 | QMessageBox::Ok); 41 | return; 42 | } 43 | 44 | //TCP已连接,准备SSL连接 45 | if (this->ctx == NULL) { 46 | this->ctx = SSL_CTX_new(NTLS_client_method()); 47 | if (this->ctx == NULL) { 48 | return; 49 | } 50 | 51 | SSL_CTX_enable_ntls(this->ctx); 52 | SSL_CTX_set_verify(this->ctx, SSL_VERIFY_NONE, NULL); 53 | } 54 | 55 | if (SSL_CTX_set_cipher_list(this->ctx, cipherList.toStdString().c_str()) != 1) { 56 | QMessageBox::warning(NULL, 57 | "set cipher list failed", 58 | QString("设置密码套件失败,请确认套件格式是否正确"), 59 | QMessageBox::Ok, 60 | QMessageBox::Ok); 61 | return; 62 | } 63 | 64 | SSL_free(this->ssl); 65 | this->ssl = SSL_new(this->ctx); 66 | SSL_set_fd(ssl, this->socket.socketDescriptor()); 67 | 68 | if (BIO_socket_nbio(this->socket.socketDescriptor(), 0) != 1) { 69 | QMessageBox::warning(NULL, 70 | "set blocking failed", 71 | QString("设置阻塞模式失败"), 72 | QMessageBox::Ok, 73 | QMessageBox::Ok); 74 | return; 75 | } 76 | 77 | ret = SSL_connect(this->ssl); 78 | if (ret == 1) { 79 | //SSL连接成功 80 | ui->pushButtonConnect->setText("断开服务器"); 81 | 82 | this->ui->textBrowserDebug->append(QString("TLCP握手成功\n")); 83 | 84 | ui->pushButtonSend->setEnabled(true); 85 | } else { 86 | err = SSL_get_error(this->ssl, ret); 87 | 88 | //SSL连接失败 89 | SSL_shutdown(this->ssl); 90 | QMessageBox::warning(NULL, 91 | "connect failed", 92 | QString("TLCP连接失败,err:%1").arg(err), 93 | QMessageBox::Ok, 94 | QMessageBox::Ok); 95 | return; 96 | } 97 | } else { 98 | ui->pushButtonConnect->setText("连接服务器"); 99 | ui->pushButtonSend->setEnabled(false); 100 | if (this->ssl != NULL) { 101 | SSL_shutdown(this->ssl); 102 | } 103 | 104 | this->ui->textBrowserDebug->append(QString("客户端关闭连接\n")); 105 | } 106 | } 107 | 108 | void TLCPclient::on_pushButtonSend_clicked() 109 | { 110 | // SSL_set_msg_callback(ssl, trace_cb); 111 | //获取发送内容 112 | QString inputQstr = this->ui->plainTextEditInput->toPlainText(); 113 | int ret = SSL_write(this->ssl, inputQstr.toStdString().c_str(), inputQstr.size()); 114 | if (ret < 0) { 115 | int err = SSL_get_error(this->ssl, ret); 116 | 117 | if (err == SSL_ERROR_SYSCALL && !socket.isOpen()) { 118 | QMessageBox::warning(NULL, 119 | "write failed", 120 | QString("TLCP发送数据失败,服务端已经关闭连接"), 121 | QMessageBox::Ok, 122 | QMessageBox::Ok); 123 | return; 124 | } else { 125 | QMessageBox::warning(NULL, 126 | "write failed", 127 | QString("TLCP发送数据失败,err:%1").arg(err), 128 | QMessageBox::Ok, 129 | QMessageBox::Ok); 130 | //发送失败 131 | // getError(); 132 | return; 133 | } 134 | } else { 135 | this->ui->textBrowserDebug->append(QString(">>>:\n") + inputQstr + QString("\n")); 136 | } 137 | 138 | char rxbuf[16384] = {0}; 139 | ret = SSL_read(this->ssl, rxbuf, sizeof(rxbuf)); 140 | if (ret < 0) { 141 | int err = SSL_get_error(this->ssl, ret); 142 | 143 | QMessageBox::warning(NULL, 144 | "read failed", 145 | QString("读失败,err:%1").arg(err), 146 | QMessageBox::Ok, 147 | QMessageBox::Ok); 148 | return; 149 | } else { 150 | // 输出到接收 151 | this->ui->textBrowserOutput->setText(QString::asprintf("%s", rxbuf)); 152 | 153 | this->ui->textBrowserDebug->append(QString("<<<:\n") + QString::asprintf("%s", rxbuf) 154 | + QString("\n")); 155 | } 156 | } 157 | 158 | void TLCPclient::trace_cb( 159 | int write_p, int version, int content_type, const void *buf, size_t msglen, SSL *ssl, void *arg) 160 | { 161 | std::shared_ptr bio(BIO_new(BIO_s_mem()), BIO_free); 162 | arg = bio.get(); 163 | SSL_trace(write_p, version, content_type, buf, msglen, ssl, arg); 164 | int len = BIO_pending((BIO *) arg); 165 | char argbuf[1024] = {}; 166 | BIO_read((BIO *) arg, argbuf, len); 167 | } 168 | -------------------------------------------------------------------------------- /tlcpclient.h: -------------------------------------------------------------------------------- 1 | #ifndef TLCPCLIENT_H 2 | #define TLCPCLIENT_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | namespace Ui { 12 | class TLCPclient; 13 | } 14 | 15 | class TLCPclient : public QWidget 16 | { 17 | Q_OBJECT 18 | 19 | public: 20 | explicit TLCPclient(QWidget *parent = nullptr); 21 | ~TLCPclient(); 22 | static void trace_cb(int write_p, 23 | int version, 24 | int content_type, 25 | const void *buf, 26 | size_t msglen, 27 | SSL *ssl, 28 | void *arg); 29 | private slots: 30 | void on_pushButtonConnect_clicked(); 31 | 32 | void on_pushButtonSend_clicked(); 33 | 34 | private: 35 | Ui::TLCPclient *ui; 36 | QTcpSocket socket; 37 | SSL_CTX *ctx; 38 | SSL *ssl; 39 | }; 40 | 41 | #endif // TLCPCLIENT_H 42 | -------------------------------------------------------------------------------- /tlcpclient.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | TLCPclient 4 | 5 | 6 | 7 | 0 8 | 0 9 | 434 10 | 426 11 | 12 | 13 | 14 | Form 15 | 16 | 17 | 18 | QLayout::SetMinimumSize 19 | 20 | 21 | 22 | 23 | 24 | 12 25 | 26 | 27 | 28 | 接收数据: 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 12 37 | 38 | 39 | 40 | 发送数据: 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 12 49 | 50 | 51 | 52 | 127.0.0.1 53 | 54 | 55 | IP地址 56 | 57 | 58 | 59 | 60 | 61 | 62 | 调试信息输出 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | Academy Engraved LET 74 | 13 75 | 76 | 77 | 78 | 服务器地址: 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 0 87 | 0 88 | 89 | 90 | 91 | 92 | 12 93 | 94 | 95 | 96 | 443 97 | 98 | 99 | 端口号 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 12 108 | 109 | 110 | 111 | 连接服务器 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 12 120 | 121 | 122 | 123 | 发送 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 12 132 | 133 | 134 | 135 | GET / HTTP/1.0 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 12 146 | 147 | 148 | 149 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> 150 | <html><head><meta name="qrichtext" content="1" /><meta charset="utf-8" /><style type="text/css"> 151 | p, li { white-space: pre-wrap; } 152 | hr { height: 1px; border-width: 0; } 153 | li.unchecked::marker { content: "\2610"; } 154 | li.checked::marker { content: "\2612"; } 155 | </style></head><body style=" font-family:'.AppleSystemUIFont'; font-size:12pt; font-weight:400; font-style:normal;"> 156 | <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Microsoft YaHei UI';"><br /></p></body></html> 157 | 158 | 159 | 160 | 161 | 162 | 163 | ECC-SM2-SM4-CBC-SM3 164 | 165 | 166 | 167 | 168 | 169 | 170 | 密码套件: 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | -------------------------------------------------------------------------------- /tserror.cpp: -------------------------------------------------------------------------------- 1 | #include "tserror.h" 2 | 3 | void getError() 4 | { 5 | unsigned long er = 0; 6 | char erbuf[512] = {0}; 7 | size_t erlen = 512; 8 | /* 获取错误号 */ 9 | er = ERR_get_error(); 10 | /* 将错误号转变为对应字符串 */ 11 | ERR_error_string_n(er, erbuf, erlen); 12 | /* 弹窗显示 */ 13 | QMessageBox::warning(NULL, 14 | "warning", 15 | QString::asprintf("%s", erbuf), 16 | QMessageBox::Close, 17 | QMessageBox::Close); 18 | return; 19 | } 20 | 21 | void printTSError() 22 | { 23 | char buf[512]; 24 | 25 | ERR_error_string_n(ERR_get_error(), buf, sizeof(buf)); 26 | 27 | QMessageBox::warning(NULL, 28 | "Error", 29 | QString::asprintf("%s", buf), 30 | QMessageBox::Close, 31 | QMessageBox::Close); 32 | 33 | return; 34 | } 35 | -------------------------------------------------------------------------------- /tserror.h: -------------------------------------------------------------------------------- 1 | #ifndef TSERROR_H 2 | #define TSERROR_H 3 | #include 4 | #include 5 | 6 | /* 错误处理函数 */ 7 | void getError(); 8 | void printTSError(); 9 | 10 | extern BIO *bio_err; 11 | 12 | #endif // TSERROR_H 13 | -------------------------------------------------------------------------------- /version.h: -------------------------------------------------------------------------------- 1 | #ifndef VERSION_H 2 | #define VERSION_H 3 | 4 | static const char *version = "1.0.0"; 5 | 6 | #endif // VERSION_H 7 | --------------------------------------------------------------------------------