zoukankan      html  css  js  c++  java
  • openssl rsa加密,解密以及X509证书的使用

    Openssl的相关使用

    生成证书

    代码实现

    Cert.h

        #ifndef _CERT_H
        #define _CERT_H
    
        ///header files
        #include <stdio.h>
        #include <string.h>
    
        #include <openssl
    sa.h>
        #include <opensslpem.h>
    
        #include <opensslevp.h>
        #include <openssl/engine.h>
        #include <opensslx509.h>
    
        enum CryptMode{
            ENCRYPT_MODE,
            DECRYPT_MODE
        };
    
        enum KeyType {
            FILE_TYPE,
            STRING_TYPE
        };
    
    
        int EncryptOrDecryptByPublicKey(char *inData, int inLen, char **outData, int *outLen, CryptMode mode, char *pubKey, KeyType type);
        int EncryptOrDecryptByPrivateKey(char *inData, int inLen, char **outData, int *outLen, CryptMode mode, char *priKey, KeyType type);
    
        int EncryptOrDecryptByX509(char *inData, int inLen, char **outData, int *outLen, int mode, char *x509CertPath);
    
    
        int X509Verify(char *rootCAPath, char *verifyCertPath);
    
        #endif ///_CERT_H
    

    Cert.cpp

        #include "Cert.h"
        #define MAX_LENGTH 4096
    
        static void FreeX509EnvirSpace(X509_STORE *x509Store, X509_STORE_CTX *x509StoreCTX);
    
        ///***********************************************/
        /// encrypt or decrypt by public key and mode
        /// params:
        ///    inData : input data to encrypt or decrypt
        ///    inLen  : input data length
        ///    outData: encrypted or decrypted data
        ///    outLen : output data length
        ///    mode   : ENCRPYT or DECRYPT
        ///    pubKey : public key file path or public key string distinguished by type
        ///    type   : 
        /// 返回值 :
        ///    iRet=0 ,加密成功
        ///    iRet=-1,加密失败
        ///***********************************************/
        int EncryptOrDecryptByPublicKey(char *inData, int inLen, char **outData, int *outLen, CryptMode mode, char *pubKey,KeyType type) {
            int iRet = -1;
    
            if (inData == NULL || strlen(inData) <= 0 || inLen <= 0 || pubKey == NULL || strlen(pubKey) <= 0) {
                return iRet;
            }
    
            RSA *RSAPubKey = NULL;
            int RSAPubKeyLen = 0;//秘钥长度
    
    
            FILE *fp = NULL;
            BIO *bio = NULL;
            switch (type) {
            case FILE_TYPE:
                ///1.打开秘钥文件
                if ((fp = fopen(pubKey, "rb")) == NULL) {
                    return iRet;
                }
    
                //2.从文件中获取公钥
                if ((RSAPubKey = PEM_read_RSA_PUBKEY(fp, NULL, NULL, NULL)) == NULL) {
                    //公钥获取失败
                    fclose(fp);
                    return iRet;
                }
                fclose(fp);
                break;
            case STRING_TYPE:
                ///1.新建BIO对象
                bio = BIO_new_mem_buf(pubKey, strlen(pubKey));
                if (bio == NULL) {
                    return iRet;
                }
                ///从BIO中获取公钥
                if ((RSAPubKey = PEM_read_bio_RSA_PUBKEY(bio, NULL, NULL, NULL)) == NULL) {
                    ERR_print_errors_fp(stdout);
                    BIO_free(bio);
                    return iRet;
                }
                BIO_free(bio);
                break;
            default:
                return iRet;
            }
            
    
            //3.获取公钥的长度
            RSAPubKeyLen = RSA_size(RSAPubKey);
    
            //4.为加密或解密后的数据分配空间
            (*outData) = (char *)malloc(RSAPubKeyLen + 1);
            memset(*outData, 0, RSAPubKeyLen + 1);
            if (*outData == NULL) {
                //空间分配失败
                if (pubKey != NULL) {
                    RSA_free(RSAPubKey);
                }
                return iRet;
            }
    
            //5.加解密数据
            switch (mode) {
            case ENCRYPT_MODE:
                if (RSA_public_encrypt(RSAPubKeyLen, (unsigned char *)inData, (unsigned char *)*outData, RSAPubKey, RSA_NO_PADDING) < 0) {
                    //加密失败
                    if (pubKey != NULL) {
                        RSA_free(RSAPubKey);
                    }
                    if (*outData != NULL) {
                        free(*outData);
                    }
                    return iRet;
                }
                *outLen = strlen(*outData);
                iRet = 0;
                break;
            case DECRYPT_MODE:
                if (RSA_public_decrypt(RSAPubKeyLen, (unsigned char *)inData, (unsigned char *)*outData, RSAPubKey, RSA_NO_PADDING) < 0) {
                    //解密失败
                    if (pubKey != NULL) {
                        RSA_free(RSAPubKey);
                    }
                    if (*outData != NULL) {
                        free(*outData);
                    }
                    return iRet;
                }
                *outLen = strlen(*outData);
                iRet = 0;
                break;
            default:
                ///模式错误
                return iRet;
            }
    
            //6.释放空间
            RSA_free(RSAPubKey);
            return iRet;
        }
    
        ///************************************************/
        /// 使用私钥进行加密
        /// 输入参数:
        ///    inData :待加密的数据
        ///    inLen  :待加密数据长度
        ///    outData:加密后的数据
        ///    outLen :加密后数据长度
        /// 返回值:
        ///    iRet=-1,加密失败
        ///    iRet=0 ,加密成功
        ///************************************************/
        int EncryptOrDecryptByPrivateKey(char *inData, int inLen, char **outData, int *outLen, CryptMode mode, char *priKey,KeyType type) {
            int iRet = -1;
    
            if (inData == NULL || inLen <= 0 || strlen(inData) <= 0 || priKey == NULL || strlen(priKey) <= 0) {
                return iRet;
            }
    
            RSA *RSAPriKey = NULL;
            int RSAPriKeyLen = 0;
    
            FILE *fp = NULL;
            BIO *bio = NULL;
            switch (type) {
            case FILE_TYPE:
                ///1.打开私钥文件
            
                if ((fp = fopen(priKey, "rb")) == NULL) {
                    ///文件打开失败
                    return iRet;
                }
    
                ///2.从文件中获取私钥
                if ((RSAPriKey = PEM_read_RSAPrivateKey(fp, NULL, NULL, NULL)) == NULL) {
                    ///获取私钥失败
                    fclose(fp);
                    return iRet;
                }
                fclose(fp);
                break;
            case STRING_TYPE:
                bio = BIO_new_mem_buf(priKey, strlen(priKey));
                if (bio == NULL) {
                    return iRet;
                }
                if ((RSAPriKey = PEM_read_bio_RSAPrivateKey(bio, NULL, NULL, NULL)) == NULL) {
                    BIO_free(bio);
                    return iRet;
                }
                BIO_free(bio);
                break;
            default:
                return iRet;
            }
    
            ///3.获取私钥长度
            RSAPriKeyLen = RSA_size(RSAPriKey);
    
            ///4.为加密或解密的内容申请空间
            (*outData) = (char *)malloc(RSAPriKeyLen + 1);
            if (*outData == NULL) {
                if (priKey != NULL) {
                    RSA_free(RSAPriKey);
                }
                return iRet;
            }
            memset(*outData, 0, RSAPriKeyLen + 1);
    
            ///5.用私钥加解密数据
            switch (mode) {
            case ENCRYPT_MODE:
                if (RSA_private_encrypt(RSAPriKeyLen, (unsigned char*)inData, (unsigned char *)*outData, RSAPriKey, RSA_NO_PADDING) < 0) {
                    ///加密失败
                    if (priKey != NULL) {
                        RSA_free(RSAPriKey);
                    }
                    if (*outData != NULL) {
                        free(*outData);
                    }
                    return iRet;
                }
                *outLen = strlen(*outData);
                iRet = 0;
                break;
            case DECRYPT_MODE:
                if (RSA_private_decrypt(RSAPriKeyLen, (unsigned char *)inData, (unsigned char *)*outData, RSAPriKey, RSA_NO_PADDING) < 0) {
                    ///解密失败
                    if (*outData != NULL) {
                        free(*outData);
                    }
                    if (priKey != NULL) {
                        RSA_free(RSAPriKey);
                    }
                    return iRet;
                }
                *outLen = strlen(*outData);
                iRet = 0;
                break;
            default:
                return iRet;
            }
    
            ///6.释放空间
            RSA_free(RSAPriKey);
            return iRet;
        }
    
        ///*********************************************/
        ///从X509证书中获取RSA,用获取的公钥进行加解密
        /// 输入参数:
        ///    inData : 明文
        ///    inLen  : 明文长度
        ///    outData: 加密或解密的数据地址
        ///    outLen : 加密或解密的数据长度
        ///    mode   : 模式,0表示加密,1表示解密
        ///    x509CertPath : 509证书地址
        /// 返回值:
        ///    iRet=0,加解密成功
        ///    iRet=-1,加解密失败
        ///*********************************************/
        int EncryptOrDecryptByX509(char *inData, int inLen, char **outData, int *outLen, int mode, char *x509CertPath) {
            int iRet = -1;
            if (inData == NULL || inLen <= 0 || strlen(inData) <= 0) {
                ///待加密或解密数据为NULL
                return iRet;
            }
    
            ///从509证书中获取公钥
            X509 *x509 = NULL;
            unsigned char *x509Buf = (unsigned char *)malloc(MAX_LENGTH);
            unsigned long x509BufLen = 0;
    
            if (x509Buf == NULL) {
                ///内存分配失败
                return iRet;
            }
            ///1.读取公钥文件
            FILE *fp = NULL;
            if ((fp = fopen(x509CertPath, "rb")) == NULL) {
                ///文件打开失败
                free(x509Buf);
                return iRet;
            }
            x509BufLen = fread(x509Buf, 1, MAX_LENGTH, fp);
            fclose(fp);
    
            ///2.将二进制格式的字符串转化为X509类型
            const unsigned char *constX509Buf = x509Buf;
            if ((x509 = d2i_X509(NULL, &constX509Buf, x509BufLen)) == NULL) {
                ///证书转换失败
                free(x509Buf);
                return iRet;
            }
            free(x509Buf);
    
            ///3.将X509中的公钥提取到EVP_PKEY中
            EVP_PKEY *ePKey = NULL;
            if ((ePKey = X509_get_pubkey(x509)) == NULL) {
                ///获取公钥失败
                X509_free(x509);
            }
            X509_free(x509);
    
            ///4.从EVP_PKEY中获取RSA公钥
            RSA *pubKey = NULL;
            if ((pubKey = EVP_PKEY_get1_RSA(ePKey)) == NULL) {
                ///获取失败
                X509_free(x509);
                EVP_PKEY_free(ePKey);
                return iRet;
            }
            EVP_PKEY_free(ePKey);
    
            ///使用公钥加密或解密
            /// mode=0 加密
            /// mode=1 解密
    
            ///5.获取公钥长度
            int pubKeyLen = 0;
            pubKeyLen = RSA_size(pubKey);
    
            ///6.为加密或解密后的数据分配空间
            (*outData) = (char *)malloc(pubKeyLen + 1);
            if (*outData == NULL) {
                ///空间分配失败  
                RSA_free(pubKey);
                return iRet;
            }
            memset(*outData, 0, pubKeyLen + 1);
    
            ///7.进行加密或解密
            switch (mode) {
            case 0:
                if (RSA_public_encrypt(pubKeyLen, (unsigned char *)inData, (unsigned char *)*outData, pubKey, RSA_NO_PADDING) <= 0) {
                    ///加密失败
                    free(*outData);
                    RSA_free(pubKey);
                    return iRet;
                }
                *outLen = strlen(*outData);
                iRet = 0;
                break;
            case 1:
                if (RSA_public_decrypt(pubKeyLen, (unsigned char *)inData, (unsigned char *)*outData, pubKey, RSA_NO_PADDING) <= 0) {
                    ///解密失败
                    free(*outData);
                    RSA_free(pubKey);
                    return iRet;
                }
                *outLen = strlen(*outData);
                iRet = 0;
                break;
            default:
                ///模式错误
                return iRet;
            }
    
            ///8.释放空间
            RSA_free(pubKey);
    
            return iRet;
        }
    
        ///*********************************************/
        /// X509二进制证书验证
        /// 输入参数:
        ///    rootCAPath     : CA证书路径
        ///    verifyCertPath : 待验证证书路径
        /// 返回值:
        ///    iRet=0,验证成功
        ///    iRet=-1,验证失败
        ///*********************************************/
        int X509Verify(char *rootCAPath,char *verifyCertPath) {
            int iRet = -1;
    
            int verifyResult = 0;
            if (rootCAPath == NULL || strlen(rootCAPath) <= 0) {
                return iRet;
            }
    
            ///1.初始化X509
            FILE *fp = NULL;
            X509_STORE *x509Store = NULL;
            X509_STORE_CTX *x509StoreCTX = NULL;
    
            x509Store = X509_STORE_new(); ///证书库,保存证书链
            x509StoreCTX = X509_STORE_CTX_new(); ///证书上下文
    
            ///2.从der(二进制)格式文件中读取CA证书到buffer中。文本格式(PEM)证书,使用PEM_read_X509方法读取。
            X509 *ca = NULL;
            unsigned char *caDer = (unsigned char *)malloc(MAX_LENGTH);
            unsigned long caLen = 0;
            if (caDer == NULL) {
                FreeX509EnvirSpace(x509Store, x509StoreCTX);
                return iRet;
            }
    
            if ((fp = fopen(rootCAPath, "rb")) == NULL) {
                FreeX509EnvirSpace(x509Store, x509StoreCTX);
                free(caDer);
                return iRet;
            }
            caLen = fread(caDer, 1, 4096, fp);
            fclose(fp);
    
            ///3.将二进制格式(der编码)CA证书转化为X509数据类型
            const unsigned char *constCADer = caDer;
            if ((ca = d2i_X509(NULL, &constCADer, caLen)) == NULL) {
                ///der格式证书转换为X509失败
                FreeX509EnvirSpace(x509Store, x509StoreCTX);
                free(caDer);
                return iRet;
            }
            ///4.加入证书存储库
            if (X509_STORE_add_cert(x509Store, ca) != 1) {
                ///证书库添加失败
                FreeX509EnvirSpace(x509Store, x509StoreCTX);
                X509_free(ca);
                free(caDer);
                return iRet;
            }
    
            ///5.读取二进制格式(der)待验证证书
            X509 *verifyCert = NULL;
            unsigned char *vcDer = (unsigned char *)malloc(MAX_LENGTH);
            unsigned long vcLen = 0;
    
            if ((fp = fopen(rootCAPath, "rb")) == NULL) {
                FreeX509EnvirSpace(x509Store, x509StoreCTX);
                X509_free(ca);
                free(caDer);
                return iRet;
            }
    
            vcLen = fread(vcDer, 1, 4096, fp);
            fclose(fp);
    
            ///6.同步骤3
            const unsigned char *constVcDer = vcDer;
            if ((verifyCert = d2i_X509(NULL, &constVcDer, vcLen)) == NULL) {
                ///证书转换失败
                FreeX509EnvirSpace(x509Store, x509StoreCTX);
                X509_free(ca);
                free(caDer);
                free(vcDer);
                return iRet;
            }
    
            
            ///7.初始化证书上下文环境
            if (X509_STORE_CTX_init(x509StoreCTX, x509Store, verifyCert, NULL) != 1) {
                FreeX509EnvirSpace(x509Store, x509StoreCTX);
                X509_free(ca);
                free(caDer);
                free(vcDer);
                return iRet;
            }
    
            ///8.进行验证
            verifyResult = X509_verify_cert(x509StoreCTX);
            if (verifyResult != 1) {
                ///验证失败
                long nCode = X509_STORE_CTX_get_error(x509StoreCTX);
                const char *pError = X509_verify_cert_error_string(nCode);
                //printf("[%s:%d] ErrorCode:%ld ErrorStr:%s
    ", __FUNCTION__, __LINE__, nCode, pError);
                return iRet;
            }
    
            iRet = (verifyResult == 1 ? 0 : -1);
            ///9.释放多余空间
            free(caDer);
            free(vcDer);
            X509_free(ca);
            X509_free(verifyCert);
                                
            X509_STORE_free(x509Store);
            X509_STORE_CTX_free(x509StoreCTX);
            return iRet;
        }
    
        static void FreeX509EnvirSpace(X509_STORE *x509Store, X509_STORE_CTX *x509StoreCTX) {
            if (x509Store != NULL) {
                free(x509Store);
            }
            if (x509StoreCTX != NULL) {
                free(x509StoreCTX);
            }
        }
    

    代码测试

    CertTest.cpp

        #include "CertTest.h"
    
        #define PUB_KEY_PATH "rsa_public.key"
        #define PRI_KEY_PATH "rsa_private.key"
        #define DER_CERT_PATH "rsa.der"
        #define CER_CERT_PATH "rsa.cer"
        #define CRT_CERT_PATH "rsa.crt"
        #define PEM_CERT_PATH "rsa.pem"
    
        int TestCert() {
    
            char *data = "Hello,world!";
            int dataLen = strlen(data);
    
            char *enData = NULL;
            int enLen = 0;
            char *base64EnData = NULL;
            int base64EnLen = 0;
    
            char *deData = NULL;
            int deLen = 0;
    
            ///文件模式
            ///公钥加密私钥解密
            EncryptOrDecryptByPublicKey(data, dataLen, &enData, &enLen, ENCRYPT_MODE, PUB_KEY_PATH, FILE_TYPE);
            Base64Encode(enData, enLen, &base64EnData, &base64EnLen);
            printf("%s
    ", base64EnData);
    
            EncryptOrDecryptByPrivateKey(enData, enLen, &deData, &deLen, DECRYPT_MODE, PRI_KEY_PATH, FILE_TYPE);
            printf("%s
    ", deData);
            printf("%d
    ", strcmp(data, deData));
    
            ///私钥加密公钥解密
            EncryptOrDecryptByPrivateKey(data, dataLen, &enData, &enLen, ENCRYPT_MODE, PRI_KEY_PATH, FILE_TYPE);
            Base64Encode(enData, enLen, &base64EnData, &base64EnLen);
            printf("%s
    ", base64EnData);
    
            EncryptOrDecryptByPublicKey(enData, enLen, &deData, &deLen, DECRYPT_MODE, PUB_KEY_PATH, FILE_TYPE);
            printf("%s
    ", deData);
            printf("%d
    ", strcmp(data, deData));
    
            ///字符串加密
            char priKeyStr[] = "-----BEGIN RSA PRIVATE KEY-----
    "
                "MIIEpQIBAAKCAQEAtMs6bXNIWoR3PhrP1NvShmFK0xSEFnhi/vnzlRU5BmNSzjP7"
                "B2HBA5qByPIu1TLCP6trpPBZrasdZNxkfJgaxeucipvZPrDgsZhEZdqZU3pB9fnG"
                "9wopx3dLP1VBV+0QA2cnte4fLtL6T3z4+sw+QQRgI59VEqWGtBYxmcE7HDgzciOt"
                "s4xUxhXGG0MVFBoJguvpCk+MT5ZQX/GnTHCrnIcsdjcLxEAIVbMqKecNVBWpE7k8"
                "hS2mK7QPwDvJEuPZ2k0pem00hyMPW2klvZhiHghRqSmZisg42WIVFR+PWMojNDPs"
                "jQerJmHh95FayCGEbs6bwLoSUeJ/oI5UVzee2QIDAQABAoIBAH93YaRVSUf4aRHy"
                "WWGb8pwn8FdN+arWCgX3OFN9+QyV7oXPhEc6Fplxz9tbVMWf2fCF7YkGpFObd0fr"
                "UzW9D/NHIMFhDBP1JRZRYrflHYELi4HfLvZxxe8KHpVyiHVzgHzFt+u/DWE4Ap8U"
                "X36DjcjNSvMSnSpeZdCGbUYYRJKppNKm2YmhVkUtG5Am1D7xC8k6dzpK6szRmVM6"
                "fcYx1l8WFG/wunlyikC5CbH5cCrf/uJWtypb3vDVeB4CWV3T9FhRORPozxSWsbld"
                "3gmcwEOc/LHkkmr1sGbNfzlfpmLiK4mSpYNy0WKjIrq4CAevIz97tzj2SiESsMJo"
                "mR5TVGECgYEA6TUWoruFEvBuKDpDYKIZfRTCiaRXWC7p0LNvxC9E321qeRQYpK3Q"
                "2OqOHre/Ua9yWIiTxKJuw1ZUznlyUkTqFg6XTVDZGnHjV39+u5kXCV36AtDtv9yI"
                "DVzqGPSJc9TQ1ibFhBu+iev+jeRS0Zx7j1gq0hXjh0EKP6ExYUGTgh0CgYEAxna9"
                "TeTxPXobyKqAUVFRUtpXmWnKp8pleyMg5Cmu+BeYm+cmBiQAsGRmggFHn238ieVe"
                "WU7My97BWSAUQH8eBTF08N29+IXGmmq/5p3CGoeJbNi8ioh0E3AokYwWad1v7gky"
                "iEb0gxjJwHrEobR6j0vxue3Hqq7RvxlzbI7wsu0CgYEAq+Vg2PSl407rs6U2kt0J"
                "MqSBvJkxdKOn3xjUcmRxPMtW5waEH6arQaiqt0Oztw8+lrmdShx8zmktO8BTHwcD"
                "EN0Sc3/7dz2pWI52qOrwCwyFQ1wjUv/IHSl2uIxPYNzmTmPnxTf6G4mjaY156l2Q"
                "yhkv/wj5XHH5jutPDaQbiZUCgYEAsq7jX4dZ/6y56SBBaXVaT8tPhUtvb0RVu9jz"
                "2xkAdFPiTbN+U5cEm8u5UyFN1+fRsGG3YZcF4iPLVrAAK9WHNMvDar1qNaBUIGEu"
                "J7cvtG0FON+mWN/kCkA39lr3Lxd0mA7l1TZ1HLcrpkWiVajFk9CfcXP5Cd5d7709"
                "Y6cKZT0CgYEAmyqqETroCLByAQ0fZCUa6VfDHl1YiTJGwjZlLJDtF+L6zyDDaZU5"
                "k9oxn7smlfxQu7aIyYHiFW8rkhCJa4vFZS0ivnOseLFH5dbXxwM0e7pjzZJsf8aO"
                "m3iWlOT3oT0DUkfOkOFvxSB9eW1BsWq2966xfLlM9OFJv8oAsWLsp74="
                "
    -----END RSA PRIVATE KEY-----
    ";
            char pubKeyStr[] = "-----BEGIN PUBLIC KEY-----
    "
                "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtMs6bXNIWoR3PhrP1NvS
    "
                "hmFK0xSEFnhi/vnzlRU5BmNSzjP7B2HBA5qByPIu1TLCP6trpPBZrasdZNxkfJga
    "
                "xeucipvZPrDgsZhEZdqZU3pB9fnG9wopx3dLP1VBV+0QA2cnte4fLtL6T3z4+sw+
    "
                "QQRgI59VEqWGtBYxmcE7HDgzciOts4xUxhXGG0MVFBoJguvpCk+MT5ZQX/GnTHCr
    "
                "nIcsdjcLxEAIVbMqKecNVBWpE7k8hS2mK7QPwDvJEuPZ2k0pem00hyMPW2klvZhi
    "
                "HghRqSmZisg42WIVFR+PWMojNDPsjQerJmHh95FayCGEbs6bwLoSUeJ/oI5UVzee
    "
                "2QIDAQAB
    "
                "-----END PUBLIC KEY-----
    ";
            ///公钥加密私钥解密
            EncryptOrDecryptByPublicKey(data, dataLen, &enData, &enLen, ENCRYPT_MODE, pubKeyStr, STRING_TYPE);
            Base64Encode(enData, enLen, &base64EnData, &base64EnLen);
            printf("%s
    ", base64EnData);
    
            EncryptOrDecryptByPrivateKey(enData, enLen, &deData, &deLen, DECRYPT_MODE, priKeyStr, STRING_TYPE);
            printf("%s
    ", deData);
            printf("%d
    ", strcmp(data, deData));
    
            ///私钥机密公钥解密
            EncryptOrDecryptByPrivateKey(data, dataLen, &enData, &enLen, ENCRYPT_MODE, priKeyStr, STRING_TYPE);
            Base64Encode(enData, enLen, &base64EnData, &base64EnLen);
            printf("%s
    ", base64EnData);
    
            EncryptOrDecryptByPublicKey(enData, enLen, &deData, &deLen, DECRYPT_MODE, pubKeyStr, STRING_TYPE);
            printf("%s
    ", deData);
            printf("%d
    ", strcmp(data, deData));
            
            ///证书自校验
            int verifyResult = -1;
            verifyResult = X509Verify(DER_CERT_PATH, DER_CERT_PATH);///0表示校验成功,1表示校验失败
            printf("%d
    ", verifyResult);
            
            return 0;
        }
    
  • 相关阅读:
    iOS开发_当一个控件被添加到父控件中会调用
    iOS_判断应用在前台还是后台
    iOS开发_ SDWebImage先下载图片保存起来,需要时再调用
    WARNING ITMS90901: "Missing fullscreen support for the latest iPad mini display.
    iOS开发_显示带HTML标签的富文本
    iOS开发_WKWebView隐藏滚动条
    iOS_获取应用当前定位授权状态
    iOS开发_判断字符串是否为空的处理
    UIAlertController和UIActivityViewController在ipad中的兼容性问题
    npm run serve报错提示js堆内存不足
  • 原文地址:https://www.cnblogs.com/Black-Cobra/p/10383309.html
Copyright © 2011-2022 走看看