关键字高亮JS

        //高亮
        this.highlightKeys = searchData.content.split(' ');
        this.highlightLength = this.highlightKeys.length;
        this.highlights = [];
        this.highlightChilds($('tweetRegion').childNodes);
        this.highlightChilds($('searchTweetPageUserList').childNodes);
        $A(this.highlights).each(function(item) {
            var tag = document.createElement('span');
            item.tag.parentNode.replaceChild(tag, item.tag);
            tag.innerHTML = item.html;
        });



    highlightChilds: function(elements) {
        var length = elements.length;
        if (length == 0) return;
        var value = "";
        var i, j, exist;
        for (i = 0; i < length; i++) {
            if (elements[i].nodeType == 3) {
                value = elements[i].nodeValue.toString().trim();
                exist = false;
                if (value != "") {
                    for (j = 0; j < this.highlightLength; j++) {
                        if (value.indexOf(this.highlightKeys[j]) > -1) {
                            exist = true;
                            value = value.replace(this.highlightKeys[j], '<span style="color:#CA4004;">' + this.highlightKeys[j] + '</span>')
                        }
                    }
                    if (exist) {
                        this.highlights.push({ tag: elements[i], html: value });
                    }
                }
            }
            this.highlightChilds(elements[i].childNodes);
        }
    },
发表在 technologys | 标签为 | 关键字高亮JS已关闭评论

Access Top 无效

  如果在查询TOP语句的后面使用Order by,而且Order by字段中有重复值的话,那么这个TOP很可能会失效,会返回所有记录,但如果无重复值,那么TOP功能还是有效的

因此,在ACCESS中使用TOP功能要注意一下order by的字段是否会有重复值

 
但为了保险起见,我们也可以采用“加入主键”的方式:
 
 Select top N from table order by col ,id

用主键作“不可能重复”的保障就可以防止此问题出现了!!

发表在 article | Access Top 无效已关闭评论

劳务费算法

1、每次收入不超过4000元,应纳个人所得税=(收入额-800)*20%
2、每次收入超过4000元,应纳个人所得税=收入额*(1-20%)*20%
3、如果每次应纳税所得额超过20000-50000元的,即每次收入在25000-62500元的,应纳个人所得税=收入额*(1-20%)*30%-2000
4、如果每次应纳税所得额超过50000元以上的,即每次收入在62500元以上的,应纳个人所得税=收入额*(1-20%)*40%-7000

发表在 finance | 劳务费算法已关闭评论

ADO RS.OPEN

recordset.Open Source,ActiveConnection,CursorType,LockType,Options

可以写成:
rs.open SQL语句,conn对象,3(游标类型),2(锁定方法)

Source
Recordset对象可以通过Source属性来连接Command对象。Source参数可以是一个Command对象名称、一段SQL命令、一个指定的数据表名称或是一个Stored Procedure。假如省略这个参数,系统则采用Recordset对象的Source属性。

ActiveConnection
Recordset对象可以通过ActiveConnection属性来连接Connection对象。这里的ActiveConnection可以是一个Connection对象或是一串包含数据库连接信息(ConnectionString)的字符串参数。

CursorType
Recordset对象Open方法的CursorType参数表示将以什么样的游标类型启动数据,包括adOpenForwardOnly、adOpenKeyset、adOpenDynamic及adOpenStatic,分述如下:

常数 常数值  说明
adOpenForwardOnly 0缺省值 启动一个只能向前移动的游标(Forward Only)
adOpenKeyset 1 启动一个Keyset类型的游标
adOpenDynamic 2 启动一个Dynamic类型的游标
adOpenStatic 3 启动一个Static类型的游标

-------------------------------------------------------------
以上几个游标类型将直接影响到Recordset对象所有的属性和方法,以下列表说明他们之间的区别。

Recordset属性 adOpenForwardOnly adOpenKeyset adOpenDynamic adOpenStatic
AbsolutePage  不支持  不支持  可读写 可读写
AbsolutePosition 不支持 不支持 可读写 可读写
ActiveConnection 可读写 可读写 可读写 可读写
BOF 只读 只读 只读 只读
Bookmark 不支持 不支持 可读写 可读写
CacheSize 可读写 可读写 可读写 可读写
CursorLocation 可读写 可读写 可读写 可读写
CursorType 可读写 可读写 可读写 可读写
EditMode 只读 只读 只读 只读
EOF 只读 只读 只读 只读
Filter 可读写 可读写 可读写 可读写
LockType 可读写 可读写 可读写 可读写
MarshalOptions 可读写 可读写 可读写 可读写
MaxRecords 可读写 可读写 可读写 可读写
PageCount 不支持 不支持 只读 只读
PageSize 可读写 可读写 可读写 可读写
RecordCount 不支持 不支持 只读 只读
Source 可读写 可读写 可读写 可读写
State 只读 只读 只读 只读
Status 只读 只读 只读 只读
AddNew 支持 支持 支持 支持
CancelBatch 支持 支持 支持 支持
CancelUpdate 支持 支持 支持 支持
Clone 不支持 不支持 不支持 不支持
Close 支持 支持 支持 支持
Delete 支持 支持 支持 支持
GetRows 支持 支持 支持 支持
Move 不支持 支持 支持 支持
MoveFirst 支持 支持 支持 支持
MoveLast     不支持 支持 支持 支持
MoveNext 支持 支持 支持 支持
MovePrevious 不支持 支持 支持 支持
NextRecordset 支持 支持 支持 支持
Open 支持 支持 支持 支持
Requery 支持 支持 支持 支持
Resync 不支持 不支持 支持 支持
Supports 支持 支持 支持 支持
Update 支持 支持 支持 支持
UpdateBatch 支持 支持 支持 支持

--------------------------------------------------------------
其中NextRecordset方法并不适用于Microsoft Access数据库。

LockType
Recordset对象Open方法的LockType参数表示要采用的Lock类型,如果忽略这个参数,那么系统会以Recordset对象的LockType属性为预设值。LockType参数包含adLockReadOnly、adLockPrssimistic、adLockOptimistic及adLockBatchOptimistic等,分述如下:

常数 常数值 说明
adLockReadOnly 1缺省值 Recordset对象以只读方式启动,无法运行AddNew、Update及Delete等方法
adLockPrssimistic 2 当数据源正在更新时,系统会暂时锁住其他用户的动作,以保持数据一致性
adLockOptimistic 3 当数据源正在更新时,系统并不会锁住其他用户的动作,其他用户可以对数据进行增、删、改的操作
adLockBatchOptimistic 4 当数据源正在更新时,其他用户必须将CursorLocation属性改为adUdeClientBatch才能对数据进行增、删、改的操作
发表在 article | 标签为 | ADO RS.OPEN已关闭评论

轻量级 Lock Free 线程安全的 Queue 的C#2.0实现

2.0里面又没有ConcurrentCollection的相关类

不得已,自己写了一个,

本来想用传统的lock实现的, 不过考虑到其中的操作非常轻量级...最终还是用了Lock Free

使用原子操作 InterLocked 替换掉常用的lock关键字

Try起头的方法都有尝试次数限制,超过限制以后就退出并返回false

public sealed class SafedQueue<T>
    {
        #region private Fields
        private int isTaked = 0;
        private Queue<T> queue = new Queue<T>();
        private int MaxCount = 1000 * 1000;
        #endregion

        public void Enqueue(T t)
        {
            try
            {
                while (Interlocked.Exchange(ref isTaked, 1) != 0)
                {
                }
                this.queue.Enqueue(t);
            }
            finally
            {
                Thread.VolatileWrite(ref isTaked, 0);
            }
        }

        public T Dequeue()
        {
            try
            {
                while (Interlocked.Exchange(ref isTaked, 1) != 0)
                {
                }
                T t = this.queue.Dequeue();
                return t;
            }
            finally
            {
                Thread.VolatileWrite(ref isTaked, 0);
            }
        }

        public bool TryEnqueue(T t)
        {
            try
            {
                for (int i = 0; i < MaxCount; i++)
                {
                    if (Interlocked.Exchange(ref isTaked, 1) == 0)
                    {
                        this.queue.Enqueue(t);
                        return true;
                    }
                }
                return false;
            }
            finally
            {
                Thread.VolatileWrite(ref isTaked, 0);
            }
        }

        public bool TryDequeue(out T t)
        {
            try
            {
                for (int i = 0; i < MaxCount; i++)
                {
                    if (Interlocked.Exchange(ref isTaked, 1) == 0)
                    {
                        t = this.queue.Dequeue();
                        return true;
                    }
                }
                t = default(T);
                return false;
            }
            finally
            {
                Thread.VolatileWrite(ref isTaked, 0);
            }
        }
    }

 

发表在 article | 标签为 | 轻量级 Lock Free 线程安全的 Queue 的C#2.0实现已关闭评论

HTML固定表头Table 简单实现

IE:
<div style="height: 250px; overflow: auto;">
<table border=1>
    <tr  style="background-color:red;position:relative;top:expression(this.offsetParent.scrollTop);">
        <th>
            head
        </th>
    </tr>   
   。。。。。。。
</table>
</div>

firefox:
<div style="height: 250px; overflow: auto;">
<table border=1>
    <tr  style="position:fixed;background-color:red;">
        <th>
            head
        </th>
    </tr>   
   。。。。。。。
</table>
</div>

如果有一些空隙   请使用padding 调节。在IE中也可以 top:expression(this.offsetParent.scrollTop-2)这样调节。

发表在 technologys | 标签为 | HTML固定表头Table 简单实现已关闭评论

c# 四舍五入

C# 中没有四舍五入函数,程序语言都没有四舍五入函数,因为四舍五入算法不科学,国际通行的是 Banker 舍入法

Bankers rounding(银行家舍入)算法,即四舍六入五取偶。事实上这也是 IEEE 规定的舍入标准。因此所有符合 IEEE 标准的语言都应该是采用这一算法的

Math.Round 方法默认的也是 Banker 舍入法

在 .NET 2.0 中 Math.Round 方法有几个重载方法
Math.Round(Decimal, MidpointRounding)
Math.Round(Double, MidpointRounding)
Math.Round(Decimal, Int32, MidpointRounding)
Math.Round(Double, Int32, MidpointRounding)

将小数值舍入到指定精度。MidpointRounding 参数,指定当一个值正好处于另两个数中间时如何舍入这个值

该参数是个 MidpointRounding 枚举

此枚举有两个成员,MSDN 中的说明是:
AwayFromZero 当一个数字是其他两个数字的中间值时,会将其舍入为两个值中绝对值较小的值。
ToEven 当一个数字是其他两个数字的中间值时,会将其舍入为最接近的偶数。

注 意!这里关于 MidpointRounding.AwayFromZero 的说明是错误的!实际舍入为两个值中绝对值较大的值。不过 MSDN 中的 例子是正确的,英文描述原文是 it is rounded toward the nearest number that is away from zero.

所以,要实现四舍五入函数,对于正数,可以加一个 MidpointRounding.AwayFromZero 参数指定当一个数字是其他两个数字的中间值时其舍入为两个值中绝对值较大的值,例:

Math.Round(3.45, 2, MidpointRounding.AwayFromZero)

不过对于负数上面的方法就又不对了

因此需要自己写个函数来处理
第一个函数:
double Round(double value, int decimals)
{
  if (value < 0)
  {
    return Math.Round(value + 5 / Math.Pow(10, decimals + 1), decimals, MidpointRounding.AwayFromZero);
  }
  else
  {
    return Math.Round(value, decimals, MidpointRounding.AwayFromZero);
  }
}

第二个函数:
double Round(double d, int i)
{
  if(d >=0)
  {
    d += 5 * Math.Pow(10, -(i + 1));
  }
  else
  {
    d += -5 * Math.Pow(10, -(i + 1));
  }
  string str = d.ToString();
  string[] strs = str.Split('.');
  int idot = str.IndexOf('.');
  string prestr = strs[0];
  string poststr = strs[1];
  if(poststr.Length > i)
  {
    poststr = str.Substring(idot + 1, i);
  }
  string strd = prestr + "." + poststr;
  d = Double.Parse(strd);
  return d;
}

参数:d表示要四舍五入的数;i表示要保留的小数点后为数。

其中第二种方法是正负数都四舍五入,第一种方法是正数四舍五入,负数是五舍六入。

备注:个人认为第一种方法适合处理货币计算,而第二种方法适合数据统计的显示。

 
发表在 article | 标签为 | c# 四舍五入已关闭评论

获取文件长度(含网络)

        /// <summary>
        /// 获取文件长度,可为本地或网络
        /// </summary>
        /// <param name="url"></param>
        protected long GetFileLength(string url)
        {
            if (string.IsNullOrEmpty(url)) return 0;

            long length = 0;
            var request = WebRequest.Create(url);
            request.Credentials = CredentialCache.DefaultCredentials;
            if (request is HttpWebRequest)
            {
                var wr = (HttpWebRequest)request;
                wr.MaximumAutomaticRedirections = 5;
                wr.MaximumResponseHeadersLength = 10;
                var wre = wr.GetResponse();
                length = wre.ContentLength;
                wre.Close();
            }
            else if (request is FileWebRequest)
            {
                var fr = (FileWebRequest)request;
                var fre = fr.GetResponse();
                length = fre.ContentLength;
                fre.Close();
            }
            else
            {
                length = 0;
            }
            return length;
        }
发表在 article | 标签为 | 获取文件长度(含网络)已关闭评论

mongodb 操作符

条件操作符 
$gt : > 
$lt : < 
$gte: >= 
$lte: <= 
$ne : !=
<> 
$in : in 
$nin: not in 
$all: all 
$not:
反匹配(1.3.3及以上版本

发表在 article | 标签为 | mongodb 操作符已关闭评论

Generating Extended Validation (EV) SSL Certificates

Just did a project for the “Innovation” team of a large corp. They wanted to see the EV SSL certificates make the IE 7 browser to go green on their test site.

To generate the EV SSL Cert request, I used the following extensions in the openssl .cnf file:

[ ev_req ]

basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment

# For the EV cert policy
certificatePolicies=ia5org,@xyzpolicy

[ ev_cert ]

basicConstraints=CA:FALSE

subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer:always

# For the EV cert policy
certificatePolicies=ia5org,@xyzpolicy

[ xyzpolicy ]

policyIdentifier=1.3.1.1.1.1
CPS.1=”http://www.xyz.com/cps-statement.html
userNotice.1=@xyznotice

[ xyznotice ]

explicitText=”Any use of this Certificate constitutes acceptance of the XYZ EV Demo”

Use the above setting in the ev.cnf file and then generate the cert request using the following command:

openssl req -config ev.cnf -key key.pem -out evreq.pem -subj “/C=US/ST=California/O=XYZ/CN=www.xyz.com” -new -reqexts ev_req

发表在 article | 标签为 , | Generating Extended Validation (EV) SSL Certificates已关闭评论

OpenSSL Command

NAME
       ca - sample minimal CA application

SYNOPSIS
       openssl ca [-verbose] [-config filename] [-name section] [-gencrl] [-revoke file] [-crl_reason reason]
       [-crl_hold instruction] [-crl_compromise time] [-crl_CA_compromise time] [-subj arg] [-crldays days] [-crl-
       hours hours] [-crlexts section] [-startdate date] [-enddate date] [-days arg] [-md arg] [-policy arg] [-key-
       file arg] [-key arg] [-passin arg] [-cert file] [-in file] [-out file] [-notext] [-outdir dir] [-infiles]
       [-spkac file] [-ss_cert file] [-preserveDN] [-noemailDN] [-batch] [-msie_hack] [-extensions section] [-extfile
       section] [-engine id]

DESCRIPTION
       The ca command is a minimal CA application. It can be used to sign certificate requests in a variety of forms
       and generate CRLs it also maintains a text database of issued certificates and their status.

       The options descriptions will be divided into each purpose.

CA OPTIONS
       -config filename
           specifies the configuration file to use.

       -name section
           specifies the configuration file section to use (overrides default_ca in the ca section).

       -in filename
           an input filename containing a single certificate request to be signed by the CA.

       -ss_cert filename
           a single self signed certificate to be signed by the CA.

       -spkac filename
           a file containing a single Netscape signed public key and challenge and additional field values to be
           signed by the CA. See the SPKAC FORMAT section for information on the required format.

       -infiles
           if present this should be the last option, all subsequent arguments are assumed to the the names of files
           containing certificate requests.

       -out filename
           the output file to output certificates to. The default is standard output. The certificate details will
           also be printed out to this file.

       -outdir directory
           the directory to output certificates to. The certificate will be written to a filename consisting of the
           serial number in hex with ".pem" appended.

       -cert
           the CA certificate file.

       -keyfile filename
           the private key to sign requests with.

       -key password
           the password used to encrypt the private key. Since on some systems the command line arguments are visible
           (e.g. Unix with the 'ps' utility) this option should be used with caution.

       -passin arg
           the key password source. For more information about the format of arg see the PASS PHRASE ARGUMENTS sec-
           tion in openssl(1).

       -verbose
           this prints extra details about the operations being performed.

       -notext
           don't output the text form of a certificate to the output file.

       -startdate date
           this allows the start date to be explicitly set. The format of the date is YYMMDDHHMMSSZ (the same as an
           ASN1 UTCTime structure).

       -enddate date
           this allows the expiry date to be explicitly set. The format of the date is YYMMDDHHMMSSZ (the same as an
           ASN1 UTCTime structure).

       -days arg
           the number of days to certify the certificate for.

       -md alg
           the message digest to use. Possible values include md5, sha1 and mdc2.  This option also applies to CRLs.

       -policy arg
           this option defines the CA "policy" to use. This is a section in the configuration file which decides
           which fields should be mandatory or match the CA certificate. Check out the POLICY FORMAT section for more
           information.

       -msie_hack
           this is a legacy option to make ca work with very old versions of the IE certificate enrollment control
           "certenr3". It used UniversalStrings for almost everything. Since the old control has various security
           bugs its use is strongly discouraged. The newer control "Xenroll" does not need this option.

       -preserveDN
           Normally the DN order of a certificate is the same as the order of the fields in the relevant policy sec-
           tion. When this option is set the order is the same as the request. This is largely for compatibility with
           the older IE enrollment control which would only accept certificates if their DNs match the order of the
           request. This is not needed for Xenroll.

       -noemailDN
           The DN of a certificate can contain the EMAIL field if present in the request DN, however it is good pol-
           icy just having the e-mail set into the altName extension of the certificate. When this option is set the
           EMAIL field is removed from the certificate' subject and set only in the, eventually present, extensions.
           The email_in_dn keyword can be used in the configuration file to enable this behaviour.

       -batch
           this sets the batch mode. In this mode no questions will be asked and all certificates will be certified
           automatically.

       -extensions section
           the section of the configuration file containing certificate extensions to be added when a certificate is
           issued (defaults to x509_extensions unless the -extfile option is used). If no extension section is
           present then, a V1 certificate is created. If the extension section is present (even if it is empty), then
           a V3 certificate is created.

       -extfile file
           an additional configuration file to read certificate extensions from (using the default section unless the
           -extensions option is also used).

       -engine id
           specifying an engine (by it's unique id string) will cause req to attempt to obtain a functional reference
           to the specified engine, thus initialising it if needed. The engine will then be set as the default for
           all available algorithms.

CRL OPTIONS
       -gencrl
           this option generates a CRL based on information in the index file.

       -crldays num
           the number of days before the next CRL is due. That is the days from now to place in the CRL nextUpdate
           field.

       -crlhours num
           the number of hours before the next CRL is due.

       -revoke filename
           a filename containing a certificate to revoke.

       -crl_reason reason
           revocation reason, where reason is one of: unspecified, keyCompromise, CACompromise, affiliationChanged,
           superseded, cessationOfOperation, certificateHold or removeFromCRL. The matching of reason is case insen-
           sitive. Setting any revocation reason will make the CRL v2.

           In practive removeFromCRL is not particularly useful because it is only used in delta CRLs which are not
           currently implemented.

       -crl_hold instruction
           This sets the CRL revocation reason code to certificateHold and the hold instruction to instruction which
           must be an OID. Although any OID can be used only holdInstructionNone (the use of which is discouraged by
           RFC2459) holdInstructionCallIssuer or holdInstructionReject will normally be used.

       -crl_compromise time
           This sets the revocation reason to keyCompromise and the compromise time to time. time should be in Gener-
           alizedTime format that is YYYYMMDDHHMMSSZ.

       -crl_CA_compromise time
           This is the same as crl_compromise except the revocation reason is set to CACompromise.

       -subj arg
           supersedes subject name given in the request.  The arg must be formatted as
           /type0=value0/type1=value1/type2=..., characters may be escaped by \ (backslash), no spaces are skipped.

       -crlexts section
           the section of the configuration file containing CRL extensions to include. If no CRL extension section is
           present then a V1 CRL is created, if the CRL extension section is present (even if it is empty) then a V2
           CRL is created. The CRL extensions specified are CRL extensions and not CRL entry extensions.  It should
           be noted that some software (for example Netscape) can't handle V2 CRLs.

CONFIGURATION FILE OPTIONS
       The section of the configuration file containing options for ca is found as follows: If the -name command line
       option is used, then it names the section to be used. Otherwise the section to be used must be named in the
       default_ca option of the ca section of the configuration file (or in the default section of the configuration
       file). Besides default_ca, the following options are read directly from the ca section:
        RANDFILE
        preserve
        msie_hack With the exception of RANDFILE, this is probably a bug and may change in future releases. Many of the configuration file options are identical to command line options. Where the option is present in the configuration file and the command line the command line value is used. Where an option is described as mandatory then it must be present in the configuration file or the command line equivalent (if any) used. oid_file
           This specifies a file containing additional OBJECT IDENTIFIERS.  Each line of the file should consist of
           the numerical form of the object identifier followed by white space then the short name followed by white
           space and finally the long name.

       oid_section
           This specifies a section in the configuration file containing extra object identifiers. Each line should
           consist of the short name of the object identifier followed by = and the numerical form. The short and
           long names are the same when this option is used.

       new_certs_dir
           the same as the -outdir command line option. It specifies the directory where new certificates will be
           placed. Mandatory.

       certificate
           the same as -cert. It gives the file containing the CA certificate. Mandatory.

       private_key
           same as the -keyfile option. The file containing the CA private key. Mandatory.

       RANDFILE
           a file used to read and write random number seed information, or an EGD socket (see RAND_egd(3)).

       default_days
           the same as the -days option. The number of days to certify a certificate for.

       default_startdate
           the same as the -startdate option. The start date to certify a certificate for. If not set the current
           time is used.

       default_enddate
           the same as the -enddate option. Either this option or default_days (or the command line equivalents) must
           be present.

       default_crl_hours default_crl_days
           the same as the -crlhours and the -crldays options. These will only be used if neither command line option
           is present. At least one of these must be present to generate a CRL.

       default_md
           the same as the -md option. The message digest to use. Mandatory.

       database
           the text database file to use. Mandatory. This file must be present though initially it will be empty.

       serialfile
           a text file containing the next serial number to use in hex. Mandatory.  This file must be present and
           contain a valid serial number.

       x509_extensions
           the same as -extensions.

       crl_extensions
           the same as -crlexts.

       preserve
           the same as -preserveDN

       email_in_dn
           the same as -noemailDN. If you want the EMAIL field to be removed from the DN of the certificate simply
           set this to 'no'. If not present the default is to allow for the EMAIL filed in the certificate's DN.

       msie_hack
           the same as -msie_hack

       policy
           the same as -policy. Mandatory. See the POLICY FORMAT section for more information.

       nameopt, certopt
           these options allow the format used to display the certificate details when asking the user to confirm
           signing. All the options supported by the x509 utilities -nameopt and -certopt switches can be used here,
           except the no_signame and no_sigdump are permanently set and cannot be disabled (this is because the cer-
           tificate signature cannot be displayed because the certificate has not been signed at this point).

           For convenience the values default_ca are accepted by both to produce a reasonable output.

           If neither option is present the format used in earlier versions of OpenSSL is used. Use of the old format
           is strongly discouraged because it only displays fields mentioned in the policy section, mishandles multi-
           character string types and does not display extensions.

       copy_extensions
           determines how extensions in certificate requests should be handled.  If set to none or this option is not
           present then extensions are ignored and not copied to the certificate. If set to copy then any extensions
           present in the request that are not already present are copied to the certificate. If set to copyall then
           all extensions in the request are copied to the certificate: if the extension is already present in the
           certificate it is deleted first. See the WARNINGS section before using this option.

           The main use of this option is to allow a certificate request to supply values for certain extensions such
           as subjectAltName.

POLICY FORMAT
       The policy section consists of a set of variables corresponding to certificate DN fields. If the value is
       "match" then the field value must match the same field in the CA certificate. If the value is "supplied" then
       it must be present. If the value is "optional" then it may be present. Any fields not mentioned in the policy
       section are silently deleted, unless the -preserveDN option is set but this can be regarded more of a quirk
       than intended behaviour.

SPKAC FORMAT
       The input to the -spkac command line option is a Netscape signed public key and challenge. This will usually
       come from the KEYGEN tag in an HTML form to create a new private key.  It is however possible to create SPKACs
       using the spkac utility.

       The file should contain the variable SPKAC set to the value of the SPKAC and also the required DN components
       as name value pairs.  If you need to include the same component twice then it can be preceded by a number and
       a '.'.

EXAMPLES
       Note: these examples assume that the ca directory structure is already set up and the relevant files already
       exist. This usually involves creating a CA certificate and private key with req, a serial number file and an
       empty index file and placing them in the relevant directories.

       To use the sample configuration file below the directories demoCA, demoCA/private and demoCA/newcerts would be
       created. The CA certificate would be copied to demoCA/cacert.pem and its private key to demoCA/pri-
       vate/cakey.pem. A file demoCA/serial would be created containing for example "01" and the empty index file
       demoCA/index.txt.

       Sign a certificate request:

        openssl ca -in req.pem -out newcert.pem

       Sign a certificate request, using CA extensions:

        openssl ca -in req.pem -extensions v3_ca -out newcert.pem

       Generate a CRL

        openssl ca -gencrl -out crl.pem

       Sign several requests:

        openssl ca -infiles req1.pem req2.pem req3.pem

       Certify a Netscape SPKAC:

        openssl ca -spkac spkac.txt

       A sample SPKAC file (the SPKAC line has been truncated for clarity):

        SPKAC=MIG0MGAwXDANBgkqhkiG9w0BAQEFAANLADBIAkEAn7PDhCeV/xIxUg8V70YRxK2A5
        CN=Steve Test
        emailAddress=steve AT openssl.org
        0.OU=OpenSSL Group
        1.OU=Another Group

       A sample configuration file with the relevant sections for ca:

        [ ca ]
        default_ca      = CA_default            # The default ca section

        [ CA_default ]

        dir            = ./demoCA              # top dir
        database       = $dir/index.txt        # index file.
        new_certs_dir  = $dir/newcerts         # new certs dir

        certificate    = $dir/cacert.pem       # The CA cert
        serial         = $dir/serial           # serial no file
        private_key    = $dir/private/cakey.pem# CA private key
        RANDFILE       = $dir/private/.rand    # random number file

        default_days   = 365                   # how long to certify for
        default_crl_days= 30                   # how long before next CRL
        default_md     = md5                   # md to use

        policy         = policy_any            # default policy
        email_in_dn    = no                    # Don't add the email into cert DN

        nameopt        = default_ca            # Subject name display option
        certopt        = default_ca            # Certificate display option
        copy_extensions = none                 # Don't copy extensions from request

        [ policy_any ]
        countryName            = supplied
        stateOrProvinceName    = optional
        organizationName       = optional
        organizationalUnitName = optional
        commonName             = supplied
        emailAddress           = optional

FILES
       Note: the location of all files can change either by compile time options, configuration file entries, envi-
       ronment variables or command line options.  The values below reflect the default values.

        /usr/local/ssl/lib/openssl.cnf - master configuration file
        ./demoCA                       - main CA directory
        ./demoCA/cacert.pem            - CA certificate
        ./demoCA/private/cakey.pem     - CA private key
        ./demoCA/serial                - CA serial number file
        ./demoCA/serial.old            - CA serial number backup file
        ./demoCA/index.txt             - CA text database file
        ./demoCA/index.txt.old         - CA text database backup file
        ./demoCA/certs                 - certificate output file
        ./demoCA/.rnd                  - CA random seed information

ENVIRONMENT VARIABLES
       OPENSSL_CONF reflects the location of master configuration file it can be overridden by the -config command
       line option.

RESTRICTIONS
       The text database index file is a critical part of the process and if corrupted it can be difficult to fix. It
       is theoretically possible to rebuild the index file from all the issued certificates and a current CRL: how-
       ever there is no option to do this.

       V2 CRL features like delta CRL support and CRL numbers are not currently supported.

       Although several requests can be input and handled at once it is only possible to include one SPKAC or self
       signed certificate.

BUGS
       The use of an in memory text database can cause problems when large numbers of certificates are present
       because, as the name implies the database has to be kept in memory.

       It is not possible to certify two certificates with the same DN: this is a side effect of how the text
       database is indexed and it cannot easily be fixed without introducing other problems. Some S/MIME clients can
       use two certificates with the same DN for separate signing and encryption keys.

       The ca command really needs rewriting or the required functionality exposed at either a command or interface
       level so a more friendly utility (perl script or GUI) can handle things properly. The scripts CA.sh and CA.pl
       help a little but not very much.

       Any fields in a request that are not present in a policy are silently deleted. This does not happen if the
       -preserveDN option is used. To enforce the absence of the EMAIL field within the DN, as suggested by RFCs,
       regardless the contents of the request' subject the -noemailDN option can be used. The behaviour should be
       more friendly and configurable.

       Cancelling some commands by refusing to certify a certificate can create an empty file.

WARNINGS
       The ca command is quirky and at times downright unfriendly.

       The ca utility was originally meant as an example of how to do things in a CA. It was not supposed to be used
       as a full blown CA itself: nevertheless some people are using it for this purpose.

       The ca command is effectively a single user command: no locking is done on the various files and attempts to
       run more than one ca command on the same database can have unpredictable results.

       The copy_extensions option should be used with caution. If care is not taken then it can be a security risk.
       For example if a certificate request contains a basicConstraints extension with CA:TRUE and the copy_exten-
       sions value is set to copyall and the user does not spot this when the certificate is displayed then this will
       hand the requestor a valid CA certificate.

       This situation can be avoided by setting copy_extensions to copy and including basicConstraints with CA:FALSE
       in the configuration file.  Then if the request contains a basicConstraints extension it will be ignored.

       It is advisable to also include values for other extensions such as keyUsage to prevent a request supplying
       its own values.

       Additional restrictions can be placed on the CA certificate itself.  For example if the CA certificate has:

        basicConstraints = CA:TRUE, pathlen:0

       then even if a certificate is issued with CA:TRUE it will not be valid.

SEE ALSO

发表在 article | OpenSSL Command已关闭评论

openssl的证书格式转换

证书转换

PKCS 全称是 Public-Key Cryptography Standards ,是由 RSA 实验室与其它安全系统开发商为促进公钥密码的发展而制订的一系列标准,PKCS 目前共发布过 15 个标准。 常用的有:
PKCS#7 Cryptographic Message Syntax Standard
PKCS#10 Certification Request Standard
PKCS#12 Personal Information Exchange Syntax Standard
X.509是常见通用的证书格式。所有的证书都符合为Public Key Infrastructure (PKI) 制定的 ITU-T X509 国际标准。
PKCS#7 常用的后缀是: .P7B .P7C .SPC
PKCS#12 常用的后缀有: .P12 .PFX
X.509 DER 编码(ASCII)的后缀是: .DER .CER .CRT
X.509 PAM 编码(Base64)的后缀是: .PEM .CER .CRT
.cer/.crt是用于存放证书,它是2进制形式存放的,不含私钥。
.pem跟crt/cer的区别是它以Ascii来表示。
pfx/p12用于存放个人证书/私钥,他通常包含保护密码,2进制方式
p10是证书请求
p7r是CA对证书请求的回复,只用于导入
p7b以树状展示证书链(certificate chain),同时也支持单个证书,不含私钥。

1. CA证书

用openssl创建CA证书的RSA密钥(PEM格式):

openssl genrsa -des3 -out ca.key 1024        

2. 创建CA证书有效期为一年

用openssl创建CA证书(PEM格式,假如有效期为一年):

openssl req -new -x509 -days 365 -key ca.key -out ca.crt -config openssl.cnf        

openssl是可以生成DER格式的CA证书的,最好用IE将PEM格式的CA证书转换成DER格式的CA证书。

3. x509转换为pfx

openssl pkcs12 -export -out server.pfx -inkey server.key -in server.crt     

4. PEM格式的ca.key转换为Microsoft可以识别的pvk格式

pvk -in ca.key -out ca.pvk -nocrypt -topvk        

5. PKCS#12 到 PEM 的转换

openssl pkcs12 -nocerts -nodes -in cert.p12 -out private.pem  
验证   
openssl pkcs12 -clcerts -nokeys -in cert.p12 -out cert.pem        

6. 从 PFX 格式文件中提取私钥格式文件 (.key)

openssl pkcs12 -in mycert.pfx -nocerts -nodes -out mycert.key     

7. 转换 pem 到到 spc

   openssl crl2pkcs7 -nocrl -certfile venus.pem  -outform DER -out venus.spc     

用 -outform -inform 指定 DER 还是 PAM 格式。例如:

openssl x509 -in Cert.pem -inform PEM -out cert.der -outform DER        

8. PEM 到 PKCS#12 的转换

openssl pkcs12 -export -in Cert.pem -out Cert.p12 -inkey key.pem        

IIS 证书

cd c:\openssl            set OPENSSL_CONF=openssl.cnf            
openssl pkcs12 -export -out server.pfx -inkey server.key -in server.crt                  

server.key和server.crt文件是Apache的证书文件,生成的server.pfx用于导入IIS

 

9. How to Convert PFX Certificate to PEM Format for SOAP

$ openssl pkcs12 -in test.pfx -out client.pem  
Enter Import Password:  MAC verified OK  Enter PEM pass phrase:  
Verifying - Enter PEM pass phrase:  

10. Private Key Convert to RSA

$ openssl rsa -in test.key -out test.rsa

Enter pass phrase for mail.xbcorp.com.key:
writing RSA key

 
发表在 article | 标签为 | openssl的证书格式转换已关闭评论

OpenSSL 配置说明

########################
# OpenSSL 配置文件示范 #
########################
# [注意]这个示范文件并不是默认设置。
HOME = . # 默认的随机数种子文件,建议设置为 /dev/random 或 /dev/urandom
RANDFILE $ENV::HOME/.rnd # 扩展对象定义
# 比如,OpenSSL中并未定义X.509证书的扩展项,在使用到的时候就会从下面对扩展对象的定义中获取。
# 定义的方法有两种,第一种(反对使用)是存储在外部文件中,也就是这里"oid_file"变量定义的文件。
#oid_file = $ENV::HOME/.oid
# 第二种是存储在配置文件的一个字段中,也就是这里"oid_section"变量值所指定的字段。
oid_section new_oids new_oids ]
# 可以在这里添加扩展对象的定义,例如可以被’ca’和’req’使用。
# 格式如下:
# 对象简称 = 对象数字ID
req ] # 生成的证书中RSA密钥对的默认长度,取值是2的整数次方。建议使用4096以上。
default_bits 1024 # 保存生成的私钥文件的默认文件名
default_keyfile privkey.pem # 生成的私钥文件是否采用口令加密保护,可以设为yes或no。
encrypt_key yes # 读取输入私钥文件时的口令,如果未设置那么将会提示输入。
# input_password = secret
# 保存输出私钥文件时的口令,如果未设置那么将会提示输入。
# output_password = secret
default_md md5 # 为一些字段设置默认的字符串类型,比如证书请求中的城市和组织名称。可能的取值和解释如下:
# default: 包含了 PrintableString, T61String, BMPString 三种类型
# pkix  : 包含了 PrintableString, BMPString 两种类型
# utf8only: 只使用 UTF8 字符串。推荐使用这个,这样可以完美的包含任意字符。
# nombstr : 包含了 PrintableString, T61String 两种类型(不使用 BMPStrings 或 UTF8String 两种多字节字符类型)
string_mask nombstr # 如果设为yes,那么不管是命令行还是配置文件中的字符串都将按照UTF-8编码看待。默认值no表示仅使用ASCII编码。
utf8 no # 如果设为no,那么 req 指令将直接从配置文件中读取证书字段的信息,而不提示用户输入。
prompt yes # 定义输入用户信息选项的"特征名称"字段名,该扩展字段定义了多项用户信息。
distinguished_name req_distinguished_name # 定义证书请求属性的字段名,该扩展字段定义了证书请求的一些属性,但openssl的证书签发工具并不使用它们。
attributes req_attributes # 证书请求扩展的字段名,该扩展字段定义了要加入到证书请求中的一系列扩展项。
# req_extensions = v3_req
x509_extensions v3_ca ##### "特征名称"字段包含了用户的标识信息 #####
req_distinguished_name ]
countryName CN  #只能使用2字母的国家代码
stateOrProvinceName BeiJin
organizationName 
组织名
commonName 
公司名 ##### 证书请求属性字段定义了证书请求的一些属性(都不是必须的) #####
req_attributes ] ##### 要加入到证书请求中的一系列扩展项 #####
v3_req ]
basicConstraints CA:FALSE
keyUsage 
nonRepudiationdigitalSignaturekeyEncipherment #### 生成自签名证书时使用的证书扩展项 #####
### 因为这部分是非必须的,所以不翻译了,事实上你完全可以删除这部分内容
v3_ca ]
# PKIX recommendation.
subjectKeyIdentifier hash
authorityKeyIdentifier 
keyid:always,issuer:always # This is what PKIX recommends but some broken software chokes on critical
# extensions.
#basicConstraints = critical,CA:true
# So we do this instead.
basicConstraints CA:true # Key usage: this is typical for a CA certificate. However since it will
# prevent it being used as an test self-signed certificate it is best
# left out by default.
# keyUsage = cRLSign, keyCertSign
ca ]
default_ca CA_default ##### 默认的CA主配置字段 #####
CA_default ] # 保存所有信息的文件夹,这个变量只是为了给后面的变量使用
dir = ./demoCA # 存放CA本身根证书的文件名
certificate $dir/cacert.pem # 存放CA自身私钥的文件名
private_key $dir/private/cakey.pem # 签发证书时使用的序列号文本文件,里面必须包含下一个可用的16进制数字。
serial $dir/serial # 存放新签发证书的默认目录,证书名就是该证书的系列号,后缀是.pem
new_certs_dir $dir/newcerts # 已生成的证书的默认保存目录
certs $dir/certs # 保存已签发证书的文本数据库文件,初始时为空。
database $dir/index.txt # 存放当前CRL编号的文件,对于v1版本的CRL则必须注释掉该行
crlnumber $dir/crlnumber # 当前CRL文件
crl $dir/crl.pem # 生成的证书撤销列表(CRL)的默认保存目录
crl_dir $dir/crl # 同一个subject是否只能创建一个证书,设为no表示可以创建多个
unique_subject yes # 签发新证书以及CRL时默认的摘要算法,可以使用:md5,md2,mdc2,sha1
default_md sha1 # 通常,证书签发的特种名称(DN)域的各个参数顺序与证书策略的参数顺序一致。
# 但是,如果这里设为yes则保持与证书请求中的参数顺序一致。
preserve no # 当用户需要确认签发证书时显示可读证书DN域的方式。可用值与 x509 指令的 -nameopt 选项相同。
name_opt ca_default
# 当用户需要确认签发证书时显示证书域的方式。
# 可用值与 x509 指令的 -certopt 选项相同,不过 no_signame 和 no_sigdump 总被默认设置。
cert_opt  ca_default # 新证书默认的生效日期,如果未设置则使用签发时的时间,格式为:YYMMDDHHNNSSZ(年月日时分秒Z)
# default_startdate = 080303223344Z
# 新证书默认的失效日期,格式为:YYMMDDHHNNSSZ(年月日时分秒Z)
# default_enddate = 090303223344Z
# 新签发的证书默认有效期,以天为单位
default_days 365 # 从当前CRL(证书撤销列表)到下次CRL发布的间隔天数
default_crl_days 30 # 是否将证书请求中的扩展项信息加入到证书扩展项中去。取值范围以及解释:
# none: 忽略所有证书请求中的扩展项
# copy: 将证书扩展项中没有的项目复制到证书中
# copyall: 将所有证书请求中的扩展项都复制过去,并且覆盖证书扩展项中原来已经存在的值。
copy_extensions none # 定义用于证书请求DN域匹配策略的字段,用于决定CA要求和处理证书请求提供的DN域的各个参数值的规则。
policy  policy_match # 定义X.509证书扩展项的字段。如果没有提供这个字段则生成X.509v1而不是v3格式的证书。
x509_extensions usr_cert # 定义生成CRL时需要加入的扩展项字段。如果没有定义则生成v1而不是v2版本的CRL。
# crl_extensions = crl_ext
policy_match ]
countryName  match
stateOrProvinceName 
match
organizationName 
match
commonName  
supplied
organizationalUnitName 
optional
emailAddress  
optional ### 下面的部分由于都是非必须的部分,因此也不翻译了。
### 事实上你完全可以从配置文件中删除这些内容
usr_cert ] # These extensions are added when ’ca’ signs a request. basicConstraints=CA:FALSE # Here are some examples of the usage of nsCertType. If it is omitted
# the certificate can be used for anything *except* object signing.
nsComment   "OpenSSL Generated Certificate" # PKIX recommendations harmless if included in all certificates.
subjectKeyIdentifier=hash
authorityKeyIdentifier
=keyid,issuer # This stuff is for subjectAltName and issuerAltname.
# Import the email address.
# subjectAltName=email:copy
# An alternative to produce certificates that aren’t
# deprecated according to PKIX.
# subjectAltName=email:move
crl_ext ] # CRL extensions.
# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL.
authorityKeyIdentifier=keyid:always,issuer:always proxy_cert_ext ]
# These extensions should be added when creating a proxy certificate basicConstraints=CA:FALSE # Here are some examples of the usage of nsCertType. If it is omitted
# the certificate can be used for anything *except* object signing.
nsComment   "OpenSSL Generated Certificate" # PKIX recommendations harmless if included in all certificates.
subjectKeyIdentifier=hash
authorityKeyIdentifier
=keyid,issuer:always # This stuff is for subjectAltName and issuerAltname.
# Import the email address.
# subjectAltName=email:copy
# An alternative to produce certificates that aren’t
# deprecated according to PKIX.
# subjectAltName=email:move
proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo 

########
# 语法 #
########
#
# 变量 = 值
#
# 语法很简单,一看就懂,但是有几点需要说明:
# 1. 字符串值最好使用双引号界定,并且其中可以使用"\n","\r","\t"这些转义序列("\"怎么表示?)。
# 2. 可以使用 ${变量名} 的形式引用同一字段中的变量,使用 ${字段名::变量名} 的形式引用其它字段中的变量。
# 3. 可以使用 ${EVP::环境变量} 的形式引用操作系统中定义的环境变量,若变量不存在则会导致错误。
# 4. 可以在默认字段定义与操作系统环境变量同名的变量作为默认值来避免环境变量不存在导致的错误。
# 5. 如果在同一字段内有多个相同名称的变量,那么后面的值将覆盖前面的值。
#

############
# 默认字段 #
############
# 此部分是默认字段[配置段],必须放在所有字段之前。
# 读取配置文件数据时,会首先根据字段名称去寻找相应的配置段,如果没有找到则会使用这里的默认字段。

# 定义 HOME 的默认值,防止操作系统中不存在 HOME 环境变量。
 

 

 

 

############################################################################################################
####################
##  证书请求配置  ##
####################
# 在申请证书之前通常需要首先生成符合 PKCS#10 标准的证书请求封装格式。
# openssl 的 req 指令实现了产生证书请求的功能,其相关选项的默认值就来自于这里的设置。
# 证书请求的配置分成几个字段,包括一个基本字段和几个附属字段。

##### 证书请求配置的"基本字段",其它附属字段都以它为入口 #####
 

 

 

 

 

# 签名默认使用的信息摘要算法,可以使用:md5,sha1,mdc2,md2
 

 

 

 

 

 

 

# 生成自签名证书时要使用的证书扩展项字段名,该扩展字段定义了要加入到证书中的一系列扩展项。
 

 

 

 

 

 

 

# Some might want this also
# nsCertType = sslCA, emailCA

# Include email address in subject alt name: another PKIX recommendation
# subjectAltName = email:copy
# Copy issuer details
# issuerAltName = issuer:copy

# DER hex encoding of an extension: beware experts only!
# obj=DER:02:03
# Where ’obj’ is a standard or added object
# You can even override a supported extension:
# basicConstraints = critical, DER:30:03:01:01:FF

############################################################################################################
####################
##  证书签发配置  ##
####################
# openssl 的 ca 指令实现了证书签发的功能,其相关选项的默认值就来自于这里的设置。

# 这个字段只是通过唯一的default_ca变量来指定默认的CA主配置字段的入口(-name 命令行选项的默认值)
 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

##### 证书请求信息的匹配策略 #####
# 变量名称是DN域对象的名称,变量值可以是:
# match: 该变量在证书请求中的值必须与CA证书相应的变量值完全相同,否则拒签。
# supplied: 该变量在证书请求中必须提供(值可以不同),否则拒签。
# optional: 该变量在证书请求中可以存在也可以不存在(相当于没有要求)。
# 除非preserve=yes或者在ca命令中使用了-preserveDN,否则在签发证书时将删除匹配策略中未提及的对象。
 

 

 

# This goes against PKIX guidelines but some CAs do it and some software
# requires this to avoid interpreting an end user certificate as a CA.

 

 

# This is OK for an SSL server.
# nsCertType   = server

# For an object signing certificate this would be used.
# nsCertType = objsign

# For normal client use this is typical
# nsCertType = client, email

# and for everything including object signing:
# nsCertType = client, email, objsign

# This is typical in keyUsage for a client certificate.
# keyUsage = nonRepudiation, digitalSignature, keyEncipherment

# This will be displayed in Netscape’s comment listbox.
 

 

 

# Copy subject details
# issuerAltName=issuer:copy

#nsCaRevocationUrl  = http://www.domain.dom/ca-crl.pem
#nsBaseUrl
#nsRevocationUrl
#nsRenewalUrl
#nsCaPolicyUrl
#nsSslServerName

 

 

# issuerAltName=issuer:copy
 

 

# This goes against PKIX guidelines but some CAs do it and some software
# requires this to avoid interpreting an end user certificate as a CA.

 

 

# This is OK for an SSL server.
# nsCertType   = server

# For an object signing certificate this would be used.
# nsCertType = objsign

# For normal client use this is typical
# nsCertType = client, email

# and for everything including object signing:
# nsCertType = client, email, objsign

# This is typical in keyUsage for a client certificate.
# keyUsage = nonRepudiation, digitalSignature, keyEncipherment

# This will be displayed in Netscape’s comment listbox.
 

 

 

# Copy subject details
# issuerAltName=issuer:copy

#nsCaRevocationUrl  = http://www.domain.dom/ca-crl.pem
#nsBaseUrl
#nsRevocationUrl
#nsRenewalUrl
#nsCaPolicyUrl
#nsSslServerName

# This really needs to be in place for it to be a proxy certificate

发表在 article | 标签为 | OpenSSL 配置说明已关闭评论

OpenSSL subjectAltName

参考:http://www.openssl.org/docs/apps/x509v3_config.html

 

SubjectAltNames

It is possible to arrange for a certificate to apply to more than one host (or Common Name) by using a certificate extension. Doing so requires

  • modifying the openssl configuration file
  • supplying the extra name information.

OpenSSL configuration file

I needed two modifications for the OpenSSL configuration file, /etc/ssl/openssl.cnf on my Ubuntu laptop. (You could modify a copy of the file and specify that on the command line, but I was lazy.)

First, enable the extensions:

[req]
req_extensions = v3_req

(In the req section, this line should already exist, but be commented out.)

Second, add an entry in the v3_req section to collect the alternative names. I set it up to read from an environment variable:

[ v3_req ]
subjectAltName=$ENV::ALTNAME

This requires the ALTNAME environment variable to be set to something meaningful every time the command is used, so it may just be easier to set the values in the file. The syntax for doing so is:

subjectAltName="DNS:<host1>,DNS:<host>" 

Or, a new section could be used:

subjectAltName=@alt_names

[alt_names]
DNS.1 = <host1>
DNS.2 = <host2>

Generating the certificate

To generate the self-signed certificate, use the (much more complex) command:

ALTNAME="DNS:<host1>,DNS:<host2>" \
  openssl req -new -x509 -key key.pem -out cert.pem -days 365 \
  -config /etc/ssl/openssl.cnf -extensions v3_req

The ALTNAME environment variable supplies the additional host names to be used in the SubjectAltName extension to the certificate. The additional -config and -extensions arguments are needed to get openssl req to read and used the extension configurations.

Theoretically, the canonical name (the hostname used for the CN of the certificate) should not be needed in the list of alternative names. However, when I tried omitting the canonical name from the alternative name list, Firefox did not allow the certificate to be used with the canonical name because it did not belong, as if the subjectAltNames extension was overriding the CN. According to all the information I have seen, it hurts nothing to add the CN to the subjectAltNames list, and may be necessary depending on whether I was or was not doing something wrong.

发表在 article | 标签为 | OpenSSL subjectAltName已关闭评论

基于 OpenSSL 的 CA 建立及证书签发

建立 CA

建立 CA 目录结构

按照 OpenSSL 的默认配置建立 CA ,需要在文件系统中建立相应的目录结构。相关的配置内容一般位于 /usr/ssl/openssl.cnf 内,详情可参见 config (1) 。在终端中使用如下命令建立目录结构:

$ mkdir -p ./demoCA/{private,newcerts}
$ touch ./demoCA/index.txt
$ echo 01 > ./demoCA/serial

产生的目录结构如下:

.
`-- demoCA/
    |-- index.txt
    |-- newcerts/
    |-- private/
    `-- serial

生成 CA 证书的 RSA 密钥对

首先,我们要为 CA 建立 RSA 密钥对。打开终端,使用如下命令生成 RSA 密钥对:

$ openssl genrsa -des3 -out ./demoCA/private/cakey.pem 2048

参数解释

genrsa

用于生成 RSA 密钥对的 OpenSSL 命令。

-des3

使用 3-DES 对称加密算法加密密钥对,该参数需要用户在密钥生成过程中输入一个口令用于加密。今后使用该密钥对时,需要输入相应的口令。如果不加该选项,则不对密钥进行加密。

-out ./demoCA/private/cakey.pem

令生成的密钥对保存到文件 ./demoCA/private/cakey.pem

2048

RSA 模数位数,在一定程度上表征了密钥强度。

该命令输出如下,用户应输入自己的密钥口令并确认:

Generating RSA private key, 2048 bit long modulus
................................................+++
.........................+++
e is 65537 (0x10001)
Enter pass phrase for ./demoCA/private/cakey.pem:<enter your pass-phrase>Verifying - Enter pass phrase for ./demoCA/private/cakey.pem:<re-enter your pass-phrase>

生成 CA 证书请求

为了获取一个 CA 根证书,我们需要先制作一份证书请求。先前生成的 CA 密钥对被用于对证书请求签名。

$ openssl req -new -days 365 -key ./demoCA/private/cakey.pem -out careq.pem

参数解释

req

用于生成证书请求的 OpenSSL 命令。

-new

生成一个新的证书请求。该参数将令 OpenSSL 在证书请求生成过程中要求用户填写一些相应的字段。

-days 365

从生成之时算起,证书时效为 365 天。

-key ./demoCA/private/cakey.pem

指定 ./demoCA/private/cakey.pem 为证书所使用的密钥对文件。

-out careq.pem

令生成的证书请求保存到文件 careq.pem

该命令将提示用户输入密钥口令并填写证书相关信息字段,输出如下:

Enter pass phrase for ./demoCA/private/cakey.pem:<enter you pass-phrase>
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) [AU]:CN
State or Province Name (full name) [Some-State]:ZJ
Locality Name (eg, city) []:HZ
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Some Ltd. Corp.
Organizational Unit Name (eg, section) []:Some Unit
Common Name (eg, YOUR name) []:Someone
Email Address []:some@email.com

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

对 CA 证书请求进行签名

在实际应用中,用户可以通过向知名 CA 递交证书请求来申请证书。但是在这里,我们需要建立的是一个根 CA ,只能由我们自己来对证书请求进行签名。所以我们让 OpenSSL 使用证书请求中附带的密钥对对该请求进行签名,也就是所谓的“ self sign ”:

$ openssl ca -selfsign -in careq.pem -out cacert.pem

参数解释

ca

用于执行 CA 相关操作的 OpenSSL 命令。

-selfsign

使用对证书请求进行签名的密钥对来签发证书。

-in careq.pem

指定 careq.pem 为证书请求文件。

-out ./demoCA/cacert.pem

指定 ./demoCA/cacert.pem 为输出的证书。

该命令要求用户输入密钥口令并输出相关证书信息,请求用户确认:

Using configuration from /usr/lib/ssl/openssl.cnf
Enter pass phrase for ./demoCA/private/cakey.pem:<enter your pass-phrase>
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: 2 (0x2)
        Validity
            Not Before: Jan 16 13:05:09 2008 GMT
            Not After : Jan 15 13:05:09 2009 GMT
        Subject:
            countryName = CN
            stateOrProvinceName = ZJ
            organizationName = Some Ltd. Corp.
            organizationalUnitName = Some Unit
            commonName = Someone
            emailAddress = some@email.com
        X509v3 extensions:
            X509v3 Basic Constraints:
                CA:FALSE
            Netscape Comment:
                OpenSSL Generated Certificate
            X509v3 Subject Key Identifier:
                75:F5:3C:CC:C1:5E:6D:C3:8B:46:A8:08:E6:EA:29:E8:22:7E:70:03
            X509v3 Authority Key Identifier:
                keyid:75:F5:3C:CC:C1:5E:6D:C3:8B:46:A8:08:E6:EA:29:E8:22:7E:70:03

Certificate is to be certified until Jan 15 13:05:09 2009 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

一步完成 CA 证书请求生成及签名

以上两个步骤可以合二为一。利用 ca 命令的 -x509 参数,通过以下命令同时完成证书请求生成和签名从而生成 CA 根证书:

$ openssl req -new -x509 -days 365 -key ./demoCA/private/cakey.pem -out ./demoCA/cacert.pem

参数解释

req

用于生成证书请求的 OpenSSL 命令。

-new

生成一个新的证书请求。该参数将令 OpenSSL 在证书请求生成过程中要求用户填写一些相应的字段。

-x509

生成一份 X.509 证书。

-days 365

从生成之时算起,证书时效为 365 天。

-key ./demoCA/private/cakey.pem

指定 cakey.pem 为证书所使用的密钥对文件。

-out ./demoCA/cacert.pem

令生成的证书保存到文件 ./demoCA/cacert.pem

该命令输出如下,用户应输入相应的字段:

Enter pass phrase for ./demoCA/private/cakey.pem:
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) [AU]:CN
State or Province Name (full name) [Some-State]:ZJ
Locality Name (eg, city) []:HZ
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Some Ltd. Corp.
Organizational Unit Name (eg, section) []:Some Unit
Common Name (eg, YOUR name) []:Someone
Email Address []:some@email.com

至此,我们便已成功建立了一个私有根 CA 。在这个过程中,我们获得了一份 CA 密钥对文件 ./demoCA/private/cakey.pem 以及一份由此密钥对签名的 CA 根证书文件 ./demoCA/cacert.pem ,得到的 CA 目录结构如下:

.

|-- careq.pem

`-- demoCA/

    |-- cacert.pem
    |-- index.txt


    |-- index.txt.attr

    |-- index.txt.old

    |-- newcerts/

    |   `-- 01.pem

    |-- private/

    |   `-- cakey.pem

    |-- serial

    `-- serial.old

注:如果在 CA 建立过程中跳过证书请求生成的步骤,则不会产生 careq.pem 文件。

签发证书

下面我们就可以利用建立起来的 CA 进行证书签发了。

生成用户证书 RSA 密钥对

参照 CA 的 RSA 密钥对生成过程,使用如下命令生成新的密钥对:

$ openssl genrsa -des3 -out userkey.pem
Generating RSA private key, 512 bit long modulus
....++++++++++++
...++++++++++++
e is 65537 (0x10001)
Enter pass phrase for userkey.pem:<enter your pass-phrase>
Verifying - Enter pass phrase for userkey.pem:<re-enter your pass-phrase>

生成用户证书请求

参照 CA 的证书请求生成过程,使用如下命令生成新的证书请求:

$ openssl req -new -days 365 -key userkey.pem -out userreq.pem
Enter pass phrase for userkey.pem:<enter your pass-phrase>
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) [AU]:CN
State or Province Name (full name) [Some-State]:ZJ
Locality Name (eg, city) []:HZ
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Some Ltd. Corp.
Organizational Unit Name (eg, section) []:Some Other Unit
Common Name (eg, YOUR name) []:Another
Email Address []:another@email.com

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

签发用户证书

现在,我们可以用先前建立的 CA 来对用户的证书请求进行签名来为用户签发证书了。使用如下命令:

$ openssl ca -in userreq.pem -out usercert.pem

参数解释

ca

用于执行 CA 相关操作的 OpenSSL 命令。

-in userreq.pem

指定用户证书请求文件为 userreq.pem

-out usercert.pem

指定输出的用户证书文件为 usercert.pem

该命令要求用户输入密钥口令并输出相关证书信息,请求用户确认:

Using configuration from /usr/lib/ssl/openssl.cnf
Enter pass phrase for ./demoCA/private/cakey.pem:<enter your pass-phrase>
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: 2 (0x2)
        Validity
            Not Before: Jan 16 14:50:22 2008 GMT
            Not After : Jan 15 14:50:22 2009 GMT
        Subject:
            countryName               = CN
            stateOrProvinceName       = ZJ
            organizationName          = Some Ltd. Corp.
            organizationalUnitName    = Some Other Unit
            commonName                = Another
            emailAddress              = another@email.com
        X509v3 extensions:
            X509v3 Basic Constraints:
                CA:FALSE
            Netscape Comment:
                OpenSSL Generated Certificate
            X509v3 Subject Key Identifier:
                97:E7:8E:84:B1:45:27:83:94:A0:DC:24:79:7B:83:97:99:0B:36:A9
            X509v3 Authority Key Identifier:
                keyid:D9:87:12:94:B2:20:C7:22:AB:D4:D5:DF:33:DB:84:F3:B0:4A:EC:A2

Certificate is to be certified until Jan 15 14:50:22 2009 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

至此,我们便完成了 CA 的建立及用户证书签发的全部工作。不妨把所有 shell 命令放到一起纵览一下:

# 建立 CA 目录结构
mkdir -p ./demoCA/{private,newcerts}
touch ./demoCA/index.txt
echo 01 > ./demoCA/serial

# 生成 CA 的 RSA 密钥对
openssl genrsa -des3 -out ./demoCA/private/cakey.pem 2048

# 生成 CA 证书请求
openssl req -new -days 365 -key ./demoCA/private/cakey.pem -out careq.pem

# 自签发 CA 证书
openssl ca -selfsign -in careq.pem -out ./demoCA/cacert.pem

# 以上两步可以合二为一
openssl req -new -x509 -days 365 -key ./demoCA/private/cakey.pem -out ./demoCA/cacert.pem

# 生成用户的 RSA 密钥对
openssl genrsa -des3 -out userkey.pem

# 生成用户证书请求
openssl req -new -days 365 -key userkey.pem -out userreq.pem

# 使用 CA 签发用户证书
openssl ca -in userreq.pem -out usercert.pem

# 吊销证书, 其中crlexts 指定是否在吊销证书中显示更新点
openssl ca -gencrl -crldays 365 -crlexts crl_ext -out %CRL_PATH% -config %DIR%openssl.cnf

了解了这些基础步骤之后,就可以通过脚本甚至 makefile 的方式来将这些工作自动化。 CA.plCA.sh 便是对 OpenSSL 的 CA 相关功能的简单封装,在 Debian 系统中,安装了 OpenSSL 后,可以在 /usr/lib/ssl/misc/ 目录下找到这两个文件。而 makefile 的解决方案则可以参考这里

参考文献

发表在 article | 标签为 , | 基于 OpenSSL 的 CA 建立及证书签发已关闭评论