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 建立及证书签发已关闭评论

Sphinx索引

Sphinx是一个基于SQL的全文检索引擎,可以结合MySQL,PostgreSQL做全文搜索,它可以提供比数据库本身更专业的搜索功能,使得应用程序更容易实现专业化的全文检索。Sphinx特别为一些脚本语言设计搜索API接口,如PHP,Python,Perl,Ruby等,同时为MySQL也设计了一个存储引擎插件。

Sphinx 单一索引最大可包含1亿条记录,在1千万条记录情况下的查询速度为0.x秒(毫秒级)。Sphinx创建索引的速度为:创建100万条记录的索引只需 3~4分钟,创建1000万条记录的索引可以在50分钟内完成,而只包含最新10万条记录的增量索引,重建一次只需几十秒。

点击查看原图

Sphinx的主要特性包括:

高速索引 (在新款CPU上,近10 MB/秒);
高速搜索 (2-4G的文本量中平均查询速度不到0.1秒);
高可用性 (单CPU上最大可支持100 GB的文本,100M文档);
提供良好的相关性排名
支持分布式搜索;
提供文档摘要生成;
提供从MySQL内部的插件式存储引擎上搜索
支持布尔,短语, 和近义词查询;
支持每个文档多个全文检索域(默认最大32个);
支持每个文档多属性;
支持断词;
支持单字节编码与UTF-8编码;

 

---------------------------------------------------------------

 

1.为什么要使用Sphinx

假设你现在运营着一个论坛,论坛数据已经超过100W,很多用户都反映论坛搜索的速度非常慢,那么这时你就可以考虑使用Sphinx了(当然其他的全文检索程序或方法也行)。

2.Sphinx是什么

Sphinx由俄罗斯人Andrew Aksyonoff 开发的高性能全文搜索软件包,在GPL与商业协议双许可协议下发行。
全文检索是指以文档的全部文本信息作为检索对象的一种信息检索技术。检索的对象有可能是文章的标题,也有可能是文章的作者,也有可能是文章摘要或内容。

3.Sphinx的特性

高速索引 (在新款CPU,10 MB/);l
高速搜索 (2-4G的文本量中平均查询速度不到0.1);l
高可用性l (CPU上最大可支持100 GB的文本,100M文档);
提供良好的相关性排名
l
支持分布式搜索;l
提供文档摘要生成;l
提供从MySQL内部的插件式存储引擎上搜索l
支持布尔,短语,l 和近义词查询;
支持每个文档多个全文检索域(默认最大32);
l
支持每个文档多属性;l
支持断词;l
支持单字节编码与UTF-8编码;l

4.下载并安装Sphinx

打开网址http://www.coreseek.cn/news/7/52/ 找到适合自己的操作系统的版本,比如我是Windows那么我就可以下载Coreseek Win32通用版本,Linux下可以下载源码包,自己编译安装。这里解释下为什么我们下载的程序叫CoreseekCoreseek是基于 Sphinx开发的一款软件,对Sphinx做了一些改动,在中文方面支持得比Sphinx好,所以我们使用之。
下载完成后,将程序解压到你想解压的地方,比如我就想解压到E盘根目录,之后修改目录名为Coreseek,大功告成Coreseek安装完成了,安装的目录是在E:\coreseek\

5.使用Sphinx

我要使用Sphinx需要做以下几件事
1)
首先得有数据
2)
建立Sphinx配置文件
3)
生成索引
4)
启动Sphinx
5)
使用之(调用apisearch.exe程序进行查询)

1件:(导入数据)
我们建立测试所需要用到得数据库、表以及数据,篇幅有限,这些在附件中都有,下载后导入MySQL即可。

2件:(建立配置文件)
接下来我们需要建立一个Sphinx的配置文件 E:\coreseek\etc\mysql.conf,将其内容改为下面这些:
source mysql
{
type = mysql
sql_host = localhost
sql_user = root
sql_pass =
sql_db = test
sql_port = 3306
sql_query_pre = SET NAMES utf8
sql_query = SELECT id,addtime,title,content FROM post
sql_attr_timestamp = addtime
}

index mysql
{
source = mysql
path = E:/coreseek/var/data/mysql
charset_dictpath = E:/coreseek/etc/
charset_type = zh_cn.utf-8
}

searchd
{
listen = 9312
max_matches = 1000
pid_file = E:/coreseek/var/log/searchd_mysql.pid
log = E:/coreseek/var/log/searchd_mysql.log
query_log = E:/coreseek/var/log/query_mysql.log
}

先讲下这个配置文件中每项的含义。
source mysql{}
定义源名称为mysql,也可以叫其他的,比如:
source xxx{}
type
数据源类型

sql_*
数据相关的配置,比如sql_host,sql_pass什么的,这些不解释鸟
sql_query
建立索引时的查询命令,在这里尽可能不使用wheregroup by,将wheregroupby的内容交给sphinx,由sphinx进行条件过滤与groupby效率会更高,注意:select 的字段必须包括一个唯一主键以及要全文检索的字段,where中要用到的字段也要select出来
sql_query_pre
在执行sql_query前执行的sql命令, 可以有多条
sql_attr
以这个开头的配置项,表示属性字段,在where,orderby,groupby中出现的字段要分别定义一个属性,定义不同类型的字段要用不同的属性名,比如上面的sql_attr_timestamp就是时间戳类型。

index mysql{} 定义索引名称为mysql,也可以叫其他的,比如:index xxx{}
source
关联源,就是source xxx定义的。

path
索引文件存放路径,比如:E:/coreseek/var/data/mysql 实际存放在E:/coreseek/var/data/目录,然后创建多个名称为mysql后缀却不同的索引文件
charset_dictpath
指明分词法读取词典文件的位置,当启用分词法时,为必填项。在使用LibMMSeg作为分词库时,需要确保词典文件uni.lib在指定的目录下
charset_type
字符集,比如charset_type = zh_cn.gbk

searchd{} sphinx守护进程配置
listen
监听端口
max_matches
最大匹配数,也就是查找的数据再多也只返回这里设置的1000
pid_file pid
文件路径
log
全文检索日志
query_log
查询日志

好了,配置文件就这样,配置的参数还有很多,大家可以自己查文档。

3件:(生成索引)
开始 -> 运行 -> 输入cmd回车,打开命令行工具
e:\coreseek\bin\indexer --config e:\coreseek\etc\mysql.conf --all
这一串东西其实就是调用indexer程序来生成所有索引

如果只想对某个数据源进行索引,则可以这样:e:\coreseek\bin\indexer --config e:\coreseek\etc\mysql.conf 索引名称(索引名称指配置文件中所定义的)
--config,--all
这些都是indexer程序的参数,想了解更多参数的朋友可以查看文档
运行命令后如果你没看到FATAL,ERROR这些东西,那么索引文件就算生成成功了,比如我看到得就是
………
省略………
using config file 'e:\coreseek\etc\mysql.conf'...
indexing index 'mysql'...
collected 4 docs, 0.0 MB
………
省略………

4件:(启动Sphinx
同样命令行下
e:\coreseek\bin\searchd --config e:\coreseek\etc\mysql.conf
运行后提示了一大堆东西
using config file 'e:\coreseek\etc\mysql.conf'...
listening on all interfaces, port=9312
accepting connections
不用管这些鸟文是啥意思,反正Sphinx是启动好了。
现在有一串鸟文的这个命令行是不能关的,因为关了Sphinx也就关了,如果觉得这样不爽,可以将Sphinx安装成系统服务,在后台运行。
安装系统服务只需在命令行中输入以下命令
e:\coreseek\bin\searchd --config e:\coreseek\etc\mysql.conf --install
安装之后记得启动这个服务,不会启动那我没法,自己google

5步:(使用Sphinx
web根目录下建立一个search目录(当然不在根目录也行,同样目录名也可以随取),复制E:\coreseek\api\ sphinxapi.php文件到search目录(sphinxapi.php这个是sphinx官方提供的api),开始php程序的编写。
search目录建立一个文件,名字叫啥都行,我管它叫index.php,其内容如下
<?php

include 'sphinxapi.php'; // 加载Sphinx API

$sc = new SphinxClient(); // 实例化Api
$sc->setServer('localhost', 9312); //
设置服务端,第一个参数sphinx服务器地址,第二个sphinx监听端口

$res = $sc->query('sphinx', 'mysql'); //
执行查询, 第一个参数查询的关键字,第二个查询的索引名称,mysql索引名称(这个也是在配置文件中定义的),多个索引名称以,分开,也可以用*表示所有索引。
print_r($res);

打印结果:
Array
(
  ………
省略………
  [matches] => Array
  (
  [2] => Array
  (
  [weight] => 2
  [attrs] => Array
  (
  [addtime] => 1282622004
  )
  )
  [4] => Array
  (
  [weight] => 2
  [attrs] => Array
  (
  [addtime] => 1282622079
  )
  )
  )
  ………
省略
………
)
Matches
中就是查询的结果了,但是仿佛不是我们想要的数据,比如titilecontent字段的内容就没有查询出来,根据官方的说明是Sphinx并没有连接到MySQL去取数据,只是根据它自己的索引内容进行计算,因此如果想用Sphinx提供的API去取得我们想要的数据,还必须以查询的结果为依据,再次查询MySQL从而得到我们想要的数据。

查询结果中键值分别表示

2唯一主键

weight权重
attrs sql_attr_*
中配置
至此,搜索引擎算是完成一大半了,剩下的大家可以自行完成。

比如:

<?php
$ids = array_keys($res['matches']); //
获取主键
$ids = join(',', $ids);
$query = mysql_query("SELECT * FROM post WHERE id IN ({$ids})");
while($row = mysql_fetch_assoc($query)) {
  .....
}

Sphinx的更多配置,程序的参数等,大家可以查看Sphinx的文档。

 

 

发表在 article | 标签为 | Sphinx索引已关闭评论