千家信息网

Linux下Oenssl命令及搭建私有CA

发表于:2025-01-22 作者:千家信息网编辑
千家信息网最后更新 2025年01月22日,一、Openssl常用命令: # openssl ? # 查看openssl的命令及子命令 # man enc # 可以直接查看子命令帮助加密: # openssl enc -des3
千家信息网最后更新 2025年01月22日Linux下Oenssl命令及搭建私有CA

一、Openssl常用命令:

 # openssl ?    # 查看openssl的命令及子命令 # man enc    # 可以直接查看子命令帮助


加密:

  # openssl enc -des3 -e -salt -in /lee/sh/test.sh -out /lee/sh/test.sh.des3    -des3:指定加密算法,可以在openssl ?中查看支持的加密算法    -e:加密,缺省参数    -salt:加盐    -in:输入文件,也就是要加密的文件    -out:输出文件,也就是加密后的密文    enter des-ede3-cbc encryption password:    # 输入加密密码    Verifying - enter des-ede3-cbc encryption password:    #确认输入加密密码


解密:

 # openssl enc -des3 -d -salt -in /lee/sh/test.sh.des3 -out /lee/sh/test1.sh    -d:解密    enter des-ede3-cbc decryption password:


散列:

# md5sum /lee/sh/test.sh    # 用MD5散列    590c2fdc61a76337dd2e1df91a217a27  /lee/sh/test.sh    # sha1sum /lee/sh/test.sh    # SHA1散列    40554fd040b5a54821280603a67e5c07818aff65  /lee/sh/test.sh    # openssl dgst -sha1 /lee/sh/test.sh    # 用openssl命令进行SHA1散列    SHA1(/lee/sh/test.sh)= 40554fd040b5a54821280603a67e5c07818aff65    # openssl dgst -md5 /lee/sh/test.sh    # 用openssl命令进行MD5散列    MD5(/lee/sh/test.sh)= 590c2fdc61a76337dd2e1df91a217a27    # openssl dgst -?    # 这样可以输出支持的命令    unknown option '-?'    options are    -c              to output the digest with separating colons    -r              to output the digest in coreutils format    -d              to output debug info    -hex            output as hex dump    -binary         output in binary form    -hmac arg       set the HMAC key to arg    -non-fips-allow allow use of non FIPS digest    -sign   file    sign digest using private key in file    -verify file    verify a signature using public key in file    -prverify file  verify a signature using private key in file    -keyform arg    key file format (PEM or ENGINE)    -out filename   output to filename rather than stdout    -signature file signature to verify    -sigopt nm:v    signature parameter    -hmac key       create hashed MAC with key    -mac algorithm  create MAC (not neccessarily HMAC)    -macopt nm:v    MAC algorithm parameters or key    -engine e       use engine e, possibly a hardware device.    -md4            to use the md4 message digest algorithm    -md5            to use the md5 message digest algorithm    -ripemd160      to use the ripemd160 message digest algorithm    -sha            to use the sha message digest algorithm    -sha1           to use the sha1 message digest algorithm    -sha224         to use the sha224 message digest algorithm    -sha256         to use the sha256 message digest algorithm    -sha384         to use the sha384 message digest algorithm    -sha512         to use the sha512 message digest algorithm    -whirlpool      to use the whirlpool message digest algorithm


生成密码串(散列值):

 # openssl passwd -?    # 详细帮助还是查看man    Usage: passwd [options] [passwords]    where options are    -crypt             standard Unix password algorithm (default)    -1                 MD5-based password algorithm    # MD5算法    -apr1              MD5-based password algorithm, Apache variant    -salt string       use provided salt    -in file           read passwords from file    -stdin             read passwords from stdin    -noverify          never verify when reading password from terminal    -quiet             no warnings    -table             format output as table    -reverse           switch table columns

但是,passwd本身是一个操作系统命令,用man查看的是操作系统那个passwd的帮助,于是whatis一下:

 # whatis passwd    sslpasswd (1ssl)     - compute password hashes    # 可以看出是sslpasswd    passwd (1)           - update user's authentication tokens    passwd (5)           - password file    # man sslpasswd    # 这样就可以查看了    # openssl passwd -1    # 使用MD5算法计算密码的(字符串)的散列值    Password:     Verifying - Password:     $1$VAehBGE.$vSHYjZqz4O3xLXgqaWTL70

注意:这个命令时默认加盐的,所以多次执行同一个密码串所得到的结果都会不同

 # openssl passwd -1 -salt VAehBGE.    # 指定salt值    Password:     $1$VAehBGE.$vSHYjZqz4O3xLXgqaWTL70    # 相同的salt结果输出一样了


生成非对称密钥:

 # openssl genrsa    # 生成RSA私钥    Generating RSA private key, 2048 bit long modulus    ...........+++    ........................+++    e is 65537 (0x10001)    -----BEGIN RSA PRIVATE KEY-----    MIIEpQIBAAKCAQEA9armbPLhXtJc70Ktvw0JJEZtWaA6MtWGjL6sr51WGhrC2wcu    XVdrQlpWXWxFjO7zlwfIs2Oo9+6LmQdmRbqlt0Jmh0RG9XxB51cKR1s8c71k/u2A    Jm6Ccg8wsxLgBVKrpFB9bZ7WsLAJ7n61mkJul49Vp/uIuGX+3HEgmgoOWObw6xiC    tMSR9c5ksobz3oI6R9ccwpOfcXBWUzVo2fc+KnuKyM1saR8HXrHBPpoyP6DT2GOv    CyLjw1l1c4jPKO6PC2CJMyM4q6EuTow/j8y+X2vCVPzferYRixH8b96HGisxqD2f    UxK1H3RPOCk8L/NiWyE2L5950FgDxUB1gRXANwIDAQABAoIBABg0S1mmoG/QOBnW    rvmo1iK90Z5H/BPwF76cNrViwg32XwZncbj+mPHDpsizlzKohFV4Dd0mz4oF9bkR    EpGCLzucDi/7mSYspO2fFMMtCQq6OU4opjyjHLUSLBEopevAVmrtBz6arLphzciy    sT/OlcjW9XCEhtbsLa0YdEbZAMrfXKdpR88CX8zIKn5ZTG2BO6vP6tfLrSVPM/Rl    5dJVLFkB4cgoZKLYDzllYPn9YerUFJnl1H+2ky/skEWf+jDoIw+zVQPhUn/kdBpU    gFEbp60FvJK5iRx81fK0liOhZHFefNGsiSSqPVVvP7qRmqgCamZYqfQdRujzZ4Io    sW4Q5FECgYEA/iTMjxSnE3x5d8jzR/s5rotEq08XlfVlkAYSxFOje0lOtdlX/OJv    02+4lf0btEOHPcdCbHIuhx6zMlx2TPaXcfgMvowKe+/bfcX76VldhQxj/xJvXzVx    acCYY2fRZc69GPsXR+PHANMjI4AZWoDeGYaqxEtMafSQnFiagatyx1kCgYEA93ZA    kHUDBHlpkg+bQLrlimMGqXGj4m7TasW/PTxEWe1WbgKuN9o7grGdnAlhKDhdAi9S    4eCNzKA4CTK8Zx9WH6izgq9oushDSofTgzozuPXiJ2PFxDl0nGQLvg2UrgzzBmSK    0GO0Il7tkkDKfZdApFgqyWbA7CrShs1rF9fsYg8CgYEA00kau5Vq9btVbO2mvGAz    a1YjZ9ygei6DGkLCVXBHiNbAVlT0XqyOVZUbO68q2ioOBKFlKq2e2vz988+FFqUn    8TtMtRnOGY2myCDSNwTxyAwuEkBsURYoTMguqO4F24MOGPefOkg3CQt/uiLkcSaT    /1rDG+CSDcCifSj4gvdbvDkCgYEAorch7xrVuhpvfXg/mMeL6XwFxGMR5PEEmT+f    6Q74zrzNyRaAIf+gg+ZwgUp1lTHCjo45jIbQFo3/aqTu10v2oGiYaMUYM0E9ZgN7    49zgZ61eYJItV0KEV9U9F2HssqmXH0v7Lt1wc+1Bf5qUyxIqkiXbNIUZM/FQbw0h    bxMuvqcCgYEA8JMQHjmx9NCUAH9ShHrrqO4qw9NCvAteShx0D/AbQALP5L56QfWQ    L0h41nNpL1E2AHAME/ZcWQzeHhrPY0+gOklBRG+mQS2MNOD31bZNUgh7LF20s4M/    1Qb1srzf9qKbhD2PG3PSSuj1UuFGT/al/L3QOnv4+ewXgL/Iyl7HAgs=    -----END RSA PRIVATE KEY-----
 # openssl genrsa -out /lee/my.key    # 生成RSA私钥同时输出
 # openssl rsa -in /lee/my.key -pubout    # 查看私钥的公钥    writing RSA key    -----BEGIN PUBLIC KEY-----    MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA9armbPLhXtJc70Ktvw0J    JEZtWaA6MtWGjL6sr51WGhrC2wcuXVdrQlpWXWxFjO7zlwfIs2Oo9+6LmQdmRbql    t0Jmh0RG9XxB51cKR1s8c71k/u2AJm6Ccg8wsxLgBVKrpFB9bZ7WsLAJ7n61mkJu    l49Vp/uIuGX+3HEgmgoOWObw6xiCtMSR9c5ksobz3oI6R9ccwpOfcXBWUzVo2fc+    KnuKyM1saR8HXrHBPpoyP6DT2GOvCyLjw1l1c4jPKO6PC2CJMyM4q6EuTow/j8y+    X2vCVPzferYRixH8b96HGisxqD2fUxK1H3RPOCk8L/NiWyE2L5950FgDxUB1gRXA    NwIDAQAB    -----END PUBLIC KEY-----
  # openssl rsa -in /lee/my.key -pubout -out /lee/mypub.key    # 输出私钥的公钥


二、配置CA:

1):查看并修改CA配置文件:

    # cat /etc/pki/tls/openssl.cnf    # 主要的是下面的内容    ####################################################################    [ ca ]    default_ca= CA_default# The default ca section        ####################################################################    [ CA_default ]        dir= /etc/pki/CA# Where everything is kept    # 默认主工作目录    certs= $dir/certs# Where the issued certs are kept    # 客户端证书保存目录    crl_dir= $dir/crl# Where the issued crl are kept    # 证书撤销列表位置    database= $dir/index.txt# database index file.    # 发放的证书列表,默认是没有这个文件的,需要自己创建    #unique_subject= no# Set to 'no' to allow creation of    # several ctificates with same subject.    new_certs_dir= $dir/newcerts# default place for new certs.    # 新生成的证书        certificate= $dir/cacert.pem # The CA certificate    # CA自己的证书(自签署证书)    serial= $dir/serial # The current serial number    # 序号,默认是没有这个文件的,需要自己创建    crlnumber= $dir/crlnumber# the current crl number    # must be commented out to leave a V1 CRL    crl= $dir/crl.pem # The current CRL    private_key= $dir/private/cakey.pem# The private key    # CA的私钥存放位置    RANDFILE= $dir/private/.rand# private random number file        x509_extensions= usr_cert# The extentions to add to the cert        # Comment out the following two lines for the "traditional"    # (and highly broken) format.    name_opt = ca_default# Subject Name options    cert_opt = ca_default# Certificate field options        # Extension copying option: use with caution.    # copy_extensions = copy        # Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs    # so this is commented out by default to leave a V1 CRL.    # crlnumber must also be commented out to leave a V1 CRL.    # crl_extensions= crl_ext        default_days= 365# how long to certify for    # 证书默认有效期    default_crl_days= 30# how long before next CRL    default_md= sha256# use SHA-256 by default    preserve= no# keep passed DN ordering


2):生成一个CA自己的非对称私钥:

 # openssl genrsa -out /etc/pki/CA/private/cakey.pem


3):生成自签署证书:

 # openssl req -new -x509 -key /etc/pki/CA/private/cakey.pem -out /etc/pki/CA/cacert.pem    -new:新建    -x509:指定自签署证书    -key:指定非对称秘钥(私钥)    -out:输出文件    -days:证书有效期    You are about to be asked to enter information that will be incorporated    into your certificate request.    What you are about to enter is what is called a Distinguished Name or a DN.    There are quite a few fields but you can leave some blank    For some fields there will be a default value,    If you enter '.', the field will be left blank.    -----    Country Name (2 letter code) [XX]:CN    State or Province Name (full name) []:GuangDong          Locality Name (eg, city) [Default City]:ShenZhen    Organization Name (eg, company) [Default Company Ltd]:test    Organizational Unit Name (eg, section) []:test    Common Name (eg, your name or your server's hostname) []:ca.test.com    Email Address []:admin@test.com
# openssl x509 -text -in cacert.pem    # 查看证书信息    Certificate:        Data:            Version: 3 (0x2)            Serial Number:                ae:af:f9:0e:f3:0e:96:bd        Signature Algorithm: sha256WithRSAEncryption            Issuer: C=CN, ST=GuangDong, L=ShenZhen, O=test, OU=test, CN=ca.test.com/emailAddress=admin@test.com            Validity                Not Before: Feb  3 07:38:39 2018 GMT                Not After : Mar  5 07:38:39 2018 GMT            Subject: C=CN, ST=GuangDong, L=ShenZhen, O=test, OU=test, CN=ca.test.com/emailAddress=admin@test.com            Subject Public Key Info:                Public Key Algorithm: rsaEncryption                    Public-Key: (2048 bit)                    Modulus:                        00:c3:91:60:ee:17:d2:14:36:75:1c:d3:95:ac:43:                        69:5c:f0:7f:a6:00:cb:7f:b2:45:5c:1e:0a:da:a9:                        ba:82:37:7f:36:9c:49:c3:2a:23:2e:b1:fa:78:87:                        aa:a5:cc:91:2f:55:0f:e5:dd:de:e8:07:46:61:9e:                        c3:dd:33:12:a1:98:f2:cb:62:00:45:1d:54:89:cb:                        28:cb:4f:b4:eb:46:df:df:ca:5b:94:81:64:c0:4f:                        fe:91:23:a0:33:cf:b8:05:27:63:cc:d2:87:c0:42:                        30:d7:1f:d6:e0:3d:61:61:6d:46:2a:99:63:b3:7f:                        70:6a:f8:96:5f:9e:f6:b6:9f:8e:44:09:cc:eb:3e:                        ac:e0:d0:97:5e:43:9a:8d:b2:f9:18:08:73:7f:39:                        d9:9b:a5:b2:4e:c7:25:93:ce:a6:ee:36:bc:22:e9:                        08:8b:17:c0:5e:af:ff:c6:ce:ea:0b:f5:a6:d3:bc:                        f7:77:76:48:f1:57:25:56:88:6b:73:bf:65:44:59:                        aa:a4:94:cd:d5:7c:4a:ca:fd:77:19:8e:42:62:3a:                        d3:4c:7c:b3:2d:73:ac:1c:70:4b:a5:26:cf:62:c0:                        2f:e0:c3:06:eb:37:6e:1d:7b:df:53:08:09:bf:e0:                        6d:d8:ee:95:6d:1f:d9:df:3e:11:8b:e0:3d:0e:7b:                        94:0f                    Exponent: 65537 (0x10001)            X509v3 extensions:                X509v3 Subject Key Identifier:                     30:2F:BF:46:D3:E2:89:32:F3:76:D8:59:72:E5:06:79:65:E3:FF:2B                X509v3 Authority Key Identifier:                     keyid:30:2F:BF:46:D3:E2:89:32:F3:76:D8:59:72:E5:06:79:65:E3:FF:2B                    X509v3 Basic Constraints:                     CA:TRUE        Signature Algorithm: sha256WithRSAEncryption             c0:d5:cc:e8:65:34:82:b5:99:f5:5d:e9:6d:43:42:c1:8c:01:             0c:09:34:df:d0:46:ca:01:7c:9b:f8:a1:08:e4:99:b1:5c:ef:             eb:6d:2d:d5:82:fa:3f:10:c9:96:ac:35:3a:1a:de:a7:37:69:             9d:20:d3:4f:19:3b:29:e8:e1:4a:7e:29:cd:5f:a1:81:f5:3e:             5d:c4:55:e6:e5:5d:c5:87:bd:4f:45:d0:3c:2c:5a:60:9b:2e:             79:23:0d:fa:80:bf:80:83:f2:09:ce:6f:94:5c:c6:21:53:f7:             58:8e:cf:8d:88:7e:c1:57:38:a3:1c:e5:02:16:af:56:51:04:             9e:ad:54:e4:70:1f:76:d9:bf:1d:38:95:e4:94:91:6d:36:87:             c4:fa:75:3d:87:53:c9:10:8d:46:81:34:44:e3:53:12:cf:31:             ca:10:48:14:c0:6f:d3:7a:3a:62:3f:04:90:f7:00:d6:c0:ce:             ea:2f:44:ad:70:36:58:20:04:f9:2a:98:b4:af:fe:b4:67:35:             1d:3b:3e:ea:ba:e4:70:8b:56:f4:d5:bd:61:05:d4:30:23:64:             c9:54:cd:96:bf:86:dd:38:41:6a:b1:4e:8d:72:ce:79:b7:fa:             51:53:c5:08:e2:d6:2f:43:b0:39:d4:c3:3c:84:b6:83:23:60:             4b:c0:9e:9d    -----BEGIN CERTIFICATE-----    MIID4zCCAsugAwIBAgIJAK6v+Q7zDpa9MA0GCSqGSIb3DQEBCwUAMIGHMQswCQYD    VQQGEwJDTjESMBAGA1UECAwJR3VhbmdEb25nMREwDwYDVQQHDAhTaGVuWmhlbjEN    MAsGA1UECgwEdGVzdDENMAsGA1UECwwEdGVzdDEUMBIGA1UEAwwLY2EudGVzdC5j    b20xHTAbBgkqhkiG9w0BCQEWDmFkbWluQHRlc3QuY29tMB4XDTE4MDIwMzA3Mzgz    OVoXDTE4MDMwNTA3MzgzOVowgYcxCzAJBgNVBAYTAkNOMRIwEAYDVQQIDAlHdWFu    Z0RvbmcxETAPBgNVBAcMCFNoZW5aaGVuMQ0wCwYDVQQKDAR0ZXN0MQ0wCwYDVQQL    DAR0ZXN0MRQwEgYDVQQDDAtjYS50ZXN0LmNvbTEdMBsGCSqGSIb3DQEJARYOYWRt    aW5AdGVzdC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDDkWDu    F9IUNnUc05WsQ2lc8H+mAMt/skVcHgraqbqCN382nEnDKiMusfp4h7qlzJEvVQ/l    3d7oB0ZhnsPdMxKhmPLLYgBFHVSJyyjLT7TrRt/fyluUgWTAT/6RI6Azz7gFJ2PM    0ofAQjDXH9bgPWFhbUYqmWOzf3Bq+JZfnva2n45ECczrPqzg0JdeQ5qNsvkYCHN/    OdmbpbJOxyWTzqbuNrwi6QiLF8Ber//GzuoL9abTvPd3dkjxVyVWiGtzv2VEWaqk    lM3VfErK/XcZjkJiOtNMfLMtc6wccEulJs9iwC/gwwbrN24de99TCAm/4G3Y7pVt    H9nfPhGL4D0Oe5QPAgMBAAGjUDBOMB0GA1UdDgQWBBQwL79G0+KJMvN22Fly5QZ5    ZeP/KzAfBgNVHSMEGDAWgBQwL79G0+KJMvN22Fly5QZ5ZeP/KzAMBgNVHRMEBTAD    AQH/MA0GCSqGSIb3DQEBCwUAA4IBAQDA1czoZTSCtZn1XeltQ0LBjAEMCTTf0EbK    AXyb+KEI5JmxXO/rbS3Vgvo/EMmWrDU6Gt6nN2mdINNPGTsp6OFKfinNX6GB9T5d    xFXm5V3Fh71PRdA8LFpgmy55Iw36gL+Ag/IJzm+UXMYhU/dYjs+NiH7BVzijHOUC    Fq9WUQSerVTkcB922b8dOJXklJFtNofE+nU9h2PJEI1GgTRE41MSzzHKEEgUwG/T    ejpiPwSQ9wDWwM7qL0StcDZYIAT5Kpi0r/60ZzUdOz7quuRwi1b01b1hBdQwI2TJ    VM2Wv4bdOEFqsU6Ncs55t/pRU8UI4tYvQ7A51MM8hLaDI2BLwJ6d    -----END CERTIFICATE-----


4):创建CA工作目录下的必要文件

 # touch /etc/pki/CA/index.txt    # 创建证书发放列表文件 # touch /etc/pki/CA/serial    # 创建序号文件 # echo "01" > /etc/pki/CA/serial    # 写入起始序号


四、向CA申请证书:

1):生成一个自己的非对称密钥

 # openssl genrsa -out /lee/my.key


2):申请证书(在这里私有CA申请流程就是一个证书生成的步骤了)

 # openssl req -new -key /lee/my.key -out /lee/my.crt    # 注意这里没有-x509的选项了,-x509代表的是自签署    You are about to be asked to enter information that will be incorporated    into your certificate request.    What you are about to enter is what is called a Distinguished Name or a DN.    There are quite a few fields but you can leave some blank    For some fields there will be a default value,    If you enter '.', the field will be left blank.    -----    Country Name (2 letter code) [XX]:CN    State or Province Name (full name) []:GuangDong    Locality Name (eg, city) [Default City]:ShenZhen    Organization Name (eg, company) [Default Company Ltd]:test    Organizational Unit Name (eg, section) []:test    Common Name (eg, your name or your server's hostname) []:www.test.com    Email Address []:www@test.com        Please enter the following 'extra' attributes    to be sent with your certificate request    A challenge password []:    An optional company name []:


3):CA签署证书:

 # openssl ca -in /lee/my.crt -out www.test.com.crt    Using configuration from /etc/pki/tls/openssl.cnf    Check that the request matches the signature    Signature ok    Certificate Details:            Serial Number: 1 (0x1)            Validity                Not Before: Feb  3 08:29:30 2018 GMT                Not After : Feb  3 08:29:30 2019 GMT            Subject:                countryName               = CN                stateOrProvinceName       = GuangDong                organizationName          = test                organizationalUnitName    = test                commonName                = www.test.com                emailAddress              = www@test.com            X509v3 extensions:                X509v3 Basic Constraints:                     CA:FALSE                Netscape Comment:                     OpenSSL Generated Certificate                X509v3 Subject Key Identifier:                     36:1E:30:68:9A:42:75:DE:EA:BE:F3:FF:EB:3C:26:5F:5B:30:4B:30                X509v3 Authority Key Identifier:                     keyid:30:2F:BF:46:D3:E2:89:32:F3:76:D8:59:72:E5:06:79:65:E3:FF:2B        Certificate is to be certified until Feb  3 08:29:30 2019 GMT (365 days)    Sign the certificate? [y/n]:y            1 out of 1 certificate requests certified, commit? [y/n]y       Write out database with 1 new entries    Data Base Updated
  [root@localhost CA]# cat index.txt    # 查看下证书颁发列表,发现已经有了一条信息,"01"就是从刚才的serial中继承来的    V190203082930Z01unknown/C=CN/ST=GuangDong/O=test/OU=test/CN=www.test.com/emailAddress=www@test.com


证书 文件 命令 加密 生成 输出 密码 对称 算法 序号 目录 帮助 输入 有效 操作系统 也就是 位置 信息 公钥 密钥 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 图形化建模软件开发 甘肃智慧社区软件开发哪儿好 奶块选哪个服务器最好 秦淮迎双节网络安全宣传进社区 平谷区现代软件开发单价 升腾服务器多少钱 虹口区品牌软件开发业务流程 php数据库链接登录界面论文 互联网贷款与金融科技关系 瀑布模型软件开发的基本过程 网络技术编程教程 广房网络技术有限公司电话 数据结构与数据库技术课视频 汇聚年轻力量 共建网络安全 长宁区品牌软件开发服务介绍 天津麒麟软件开发公司 服务器与域名 西藏第三方软件开发定制价位 网络安全等级保护标准2.0 互联网公司科技产品 网络技术员面试注意什么 我的世界在哪玩服务器 图形化建模软件开发 雄升科技软件开发 珠海安检服务器散热器厂商 网络安全的十大应用场景 美团外卖用的什么地图数据库 域控服务器 管理外网连接 gis软件开发工具有哪些 拾柒网络技术北京有限公司官网
0