Cer.exe

See full help below...

Generating CA certificate and user certificate request

To generate a self-signed CA certificate:
cer.exe -gencert Out.pfx Out.cer -subj "/C=CZ/O=Org/OU=OrgUnit/CN=name" -bits 2048 -serial 1 -isca -notafter 31.12.2029 -128
To generate a user CSR certification request:
cer.exe -gencsr Out.pfx Out.csr -subj "/.../CN=name" -bits 2048 -128
Stores private key in Out.pfx file.
Stores CA certificate in Out.cer file, or user CSR request in Out.csr file.
For user CSR, the private key is in PFX, where is also a temporary CER self-signed certificate, that will be replaced later...
See Subject syntax...
Parameter -128 uses stronger encryption of public part in PFX file, but prevents importing certificate into WinXP.

Instead of using PFX format, the private key may be encrypted for usage on current computer only:
cer.exe -gencert Out.p7 ... -dh "#..."
This produces PKCS#7 enveloped for KeyAgree recipient (ES-DH ephemeral-static DH) for internal pseudo-random DH key. Names of pseudo-random keys are:
Machine- and user-specific DH keys are hard to export from current computer, depend on values in registry. (Machine-specific key needs to be initialized by Administrator...)
HD-specific key can be written into hard-disk by disk-editor (requires Administrator privileges both for your editing and for cer.exe reading that) and cannot be exported from outside even by user with Administrator privileges (without logging into this computer). (Registry can be accessed remotelly, but physical disk cannot...?)
(Note: cer.exe does not write to disk low-level, but can read, if you instruct it to do it...)

Specifying passwords

When password is required, it is asked on console.
Alternativelly, it may be given in parameter:
  -passfile File.dat        load password from file
  -pass -                   get password from stdin
  -pass env:VariableName    get password from environment
When In/Out passwords are needed (Input is PFX and output is modified PFX), they can be specified different:
  -passin ...  -passout ...
For opening PFX certificate, password is automatically read from PFX_PASSWORD environment variable, if exists and no other is specified...

Make user certificate by CA from CSR request

To make a user certificate (by CA), user subject and public key is read from CSR request.
cer.exe -signcert InReq.csr OutCert.cer -ca CaFile.inf -sec CA ...
cer.exe -signcert InReq.csr OutCert.cer -ca cakey.pfx ...
cer.exe -signcert InReq.csr OutCert.cer -ca CaCert.cer -cakey PrivFile.p7 -dh "#..." ...

  -serial 12345             specify serial number
  -genserial                generate large random serial number
                            (without there options, next number from IndexFile is used)
  
  -index File.idx           specify IndexFile (better from CaFile.inf)
  -ext file.asn1            load extensions from file
  -ext "values"             specify extension templates
                            (see below ExtSectionName, how to enter templates in CaFile.inf ...)
To certify a DH public key, to the -signcert may be added params:
  cer.exe -signcert "#Machine:1234" -subj "/C=CZ/.../CN=name" ...
    ... -tempca             use temporary CA certificate (discarded after use)

  cer -signcert "#hd:C:1000+1000" DHHD_1000_1000.cer -ca TestCA2.p7 -dh "#hd:C:1000+1000"
      -subj "/C=CZ/O=Semi/OU=Testing/CN=Test DH key C1000/1000" -genserial -notafter 1.1.2020 -128
      -cakey "#Machine:123"

  cer -signcert "#hd:C:1000+1000" DHHD_1000_1000.cer -tempca
      -subj "/C=CZ/O=Semi/OU=Testing/CN=Test DH key C1000/1000" -genserial -notafter 1.1.2020 -128


If CA values are read from CaFile.inf, it has ini-file format:

[CA]
; PFX file defaults to CaFile.pfx - changed extension from IniFile name...
Pfx=CaKey.pfx
; ValidDays= - default validity of user certificates
ValidDays=730
; Ext=SectionName | FileName | single line - extensions
Ext=ExtSectionName
; IndexFile - list of issued certificates
IndexFile=UserCerts.idx

[ExtSectionName]
CaCertUrl(url="http://server/file.cer")   # specify CA certificate URL... 1.3.6.1.5.5.7.1.1 : id-pe-authorityInfoAccess
CrlUrl(url="http://server/file.crl")   #specify CRL URL... 2.5.29.31 CRL Distribution Points

# CodeSign  - set 2.5.29.37 Extended Key usage to 1.3.6.1.5.5.7.3.3 id_kp_codeSigning

#OCSP url:
# OcspUrl(Url="http://...")

# IsCa  # if generating middle-CA certificates
# IsCa(MaxMiddleCa=1)  # if generating multi-level middle-CA certificates

# Subject alt-name
# AltName(Url="server.cz")
# AltName(email="admin@server.cz")

# User notice (bother user on every certificate usage?)
# UserNotice(Policy=oid,Text="...")

# CPS statement:
# CpsUrl(Policy=oid,Url="http://.../file.pdf")


Alternativelly, CA key may be encrypted in PKCS#7 ES-DH:
(i.e. using CA key without user entering password...)

[CA]
; Cert= specifies CA public key
Cert=CaFile.cer
; Key= specifies PKCS#7-encrypted private key
Key=CaFile.p7
; DH= is DH key used to decrypt private key file
DH="#Machine:1029"

Verify certificate

To verify certificate, program needs CA certificate...
Cmd> cer -testcer TestUser1.cer
File "TestUser1.cer" bad: 0x800B0109 not trusted

Cmd> cer -testcer TestUser1.cer -cafile TestCA4.cer
File "TestUser1.cer" ok
CN:     "Test User 1"
Issuer: "TestCA4"
ThumbPrint:     58FE AFE4 D703 26D4 EC61 4EAE 1484 88BD 976D AA1F

Replace CER in PFX

cer.exe -repfx In.pfx In.cer Out.pfx
  ... -pass env:VARNAME
  ... -passin env:VARNAME
  ... -passout env:VARNAME
Replace CA-signed certificate in existing PFX file.
Asks 2x password...

Export CER from PFX

To export public certificate from private PFX:
cer.exe -pfx2cer Input.pfx Output.cer
To generate new CSR request from existing PFX key:
cer.exe -pfx2csr Input.pfx Output.csr
cer.exe -pfx2csr Input.pfx Output.csr -subj "/C=CZ/CN=New name"
  ... -pem                  use PEM text output format (default binary)

Convert PFX to P7

To convert private PFX key for automated use on specific computer, can use:
cer.exe -pfxconvert -in file.pfx -out file.p7 -fmt p7 -pkey Machine.cer
(here Machine.cer would be DH-certificate of recipient of file file.p7...)

Export machine-specific DH key on that machine:
cer.exe -signcert "#Machine:1029" Machine.cer -subj "/C=CZ/CN=ComputerName" -ca CaFile.inf ...

Change password in PFX

cer.exe -pfxrepass Input.pfx Output.pfx

Using private key

For signing and decrypting, private key is required...
Either from PFX file:
 -pfx file.pfx                      -- asks password as needed
 -pfx file.pfx -pass env:PASSWORD   -- is in environment?
or from P7 (PKCS#7) + machine-specific DH key:
 -pfx file.p7 -dh "#Machine:1029"
Decrypting for DH recipient:
  -dh "#Machine:1029"        -- if someone encrypted to me?
  -dh DhPrivate.asn          -- private key ? (uses my default DhParams...?)
To encrypt data for use on specific computer, on that computer export public key "#Machine:number" into certificate and use it for encrypting...

Using public key

For verifying and encrypting, public key is required...
Public key is in *.cer file...
  -cer file.cer
Encrypting for DH recipient:
Either specify
  -cer CerDH.cer             -- certificate with DH key
  -dh DhPublic.asn           -- public key in ASN.1 INTEGER format (uses my default DhParams...)
  -dh "#Machine:1029"        -- local machine specific recipient?

TimeStamp

Currently, for HTTP access is using SynHttp.dll, which may change later...

Static solution without cer.exe accessing network:
To export TimeStamp request from PKCS#7 signed data:
cer.exe -tsr -in file.p7s -out tsr.req -reqcer
Then send the request to TSA:
wg.exe http://time.trustport.cz:8000/ -post-file=tsr.req -o tsr.resp
wg.exe https://freetsa.org/tsr -post-file=file.tsq -o file.tsr --header="Content-Type: application/timestamp-query"
Then import the time-stamp into PKCS#7 Unsigned attributes:
cer.exe -addts -in file.p7s -ts tsr.resp -out file.p7st

When SynHttp.dll is available, the -ts parameter can use syntax:
-ts http://time.server.cz
-ts t1
Where t1 is defined in Cer.ini file:
[TSA]
#testing TSA
t1=http://time.trustport.cz:8000
This way, it can also be used already at time of signing with command -sign ...

Help

cer.exe /?
Usage: Cer.exe -op -flags...
Ops can be:

[PKCS#7]
 -sign Certificate.pfx -in File.bin -out File.p7
    -detach               	Detached signature (default)
    -attach               	Include file data
    -addcert              	Include certificate
    -kid                  	Use SubjectKeyId instead of Issuer+SerialNo
    -ci                   	Generate contentIdentifier attribute
    -eid                  	Add ESSCertID attribute
    -text "Archive"       	Signed contents instead of -in File ...
    -ref File.p7          	Reference other P7-signed by contentIdentifier
    -sa attribute         	Add signed attribute(s) from file or tmpl(?)
    -ua attribute         	Add unsigned attribute(s) from file or tmpl(?)
    -addcf file.cer       	Add other certificate
 -verify [Certificate.cer] -in File.p7 -content Content.bin -out Content.bin
    -out file             	If sign contains data, unpack it
    -content file         	If sign is detached, get signed data here
    -offset 123           	Read sign at this offset in file
    -range from-to        	Specify Content-Range (if not included in signature)
 -enc -cer Certificate.cer -in File.bin -out File.p7
   -dh DhPublic.asn       	For Ephemeral-Static DH-DH, specify recipient
 -dec -pfx Certificate.pfx -in File.p7  -out File.bin
   -dh DhPrivate.asn      	For DH-DH, specify recipient (me)
   -dh "#Machine:123"     	Machine-specific pseudo-random DH

[X509]
 -gencert Out.pfx Out.cer 	Generate self-signed certificate
 -genreq Out.pfx Out.cer  	Generate certificate request
    -subj "/C=CZ/O=Org/OU=OrgUnit/CN=name/E=email@address" 
    -bits 2048            	Specify RSA bits (default 2048)
    -serial 12345         	Specify serial number (default 1)
    -genserial            	Generate new serial
    -notafter date        	Specify validity
    -days 730             	Specify validity
    -isca                 	Make CA certificate
    -128                  	Use 128-bit cipher for PFX CER blob
 -repfx In.pfx In.Cer Out.pfx 	Replace CER in PFX
 -pfxrepass In.pfx Out.pfx	Change password in PFX
 -pfx2cer In.pfx Out.cer  	Export CER from PFX
 -pfx2csr In.pfx Out.csr  	Export CSR request from PFX
 -pfxconvert ...          	Convert private key
   -in file -out file     	Input/output
   -fmt Pem|P7            	Pem=Old weak PEM fmt?, P7=Pass-encrypt PKCS#7
   -dh file.dh            	DH-DH ephemeral-static
 -signcert Req.csr Out.cer	Sign certificate by CA
    -ca CaFile.inf -sec CA	Specify CA information
   or:
    -ca File.pfx          	or just CA certificate
    -ca File.cer -cakey File.p7	other format of private key
      -dh "#internal..."  	Internal CA DH key to decrypt CA private key
    -serial 12345 -genserial	(Required, could be also from indexfile)
    -ext File.asn1        	(Optional parameter)
    -ext "values"         	User-cert Extensions
    -indexfile File.idx   	Generate index of issued certificates
    -pk DhKey.asn|"#int.."	Put this key into certificate instead
      -subj Subject       	Specify subject for DH key...
 -tsr ... -out file.asn   	Generate TSA request
    -sha infile.txt       	SHA-1 digest of file
    -in digest.bin        	20-byte digest
    -in Signed.p7s        	Make digest of signature
      -idx 1              	Different index (0-based, default 0)
    -reqcer               	Request TSA certificate
 -addts in.p7 tm.tsr out.p7	Add TimeStamp Response to PKCS#7 signed
 -addts -in f.p7 -ts tm.p7 -out f.p7	
    -ts t1     - load from cer.ini [TSA] t1=http://time.xx.org/ 
    -timeout 20           	Specify HTTP timeout in sec
 -au File.p7 oid File.asn 	Add unsigned attribute to PKCS#7 signed
 -makecrl List.txt File.crl	Compile CRL
   -ca File.pfx -next date	(required params for -makecrl)
 -type file               	Detect file-type

 -testcer File.cer        	Test certificate CER
   -cafile CaFile.pem     	Load CA certificates for verification
 -testpfx File.pfx        	Test certificate PFX
 -exec 'Command'          	Execute Command and wait
   -ign                   	Ignore exit-code...
 -dirhash Path -out File.zip	Print hash of files in path
 -dirhash Path\*.x        	(can select only some files)
   -r  , -aj              	recurse , add junctions
   -wc | -nowc            	Use Write-cache (experimental) - large catalog?
   -in File.zip           	Use old catalog and only update
 -dirhash Zile.zip -a VolName C:\Path	Add to catalog with "VolName" alias
 -dumpctg File.zip -out File.xml -xml|-noxml	Export catalog
   -fmt "%n %m %h"        	Specify format
 -zipsign File.zip File.pfx	Append special signature to ZIP archive
   -out File.asn          	(Output to another file)
 -verify file.zip\$sign.p7s -zipverify 
 -collection Output.asn ..	Build contentCollection
   -add File.bin -attr name=value 	Add file to collection


Other flags can be:
  -append file            	Instead or -out file, this appends to file-end
  -range from-to          	Specify range for -sign
                          	-range -2m- == last 2Mb, -range * == all
    -rn                   	Add FileName in ContentIdentifier range attr
  -pem                    	PEM output
  -xml                    	XML output for -sign, input for -verify 
  -xml -offset 10000      	For -verify, load XML signature at that offset
  -dhparams file.pem      	Change default DH parameters
  -@ file                 	Load parameters from file
  -@ -                    	Load parameters from stdin
  --                      	Flush command queue

 For PFX handling, specify password:
    -pass ?                       	Prompt password
    -passfile File.dat            	Load password from file
    -pass -                       	Load password from stdin
    -pass env:VarName             	Get password from env variable
                                  	(default is PFX_PASSWORD)
    -cfg File.ini Section         	Load params from IniFile [Section]
    -q                            	Ask command-line on console
    -qp Prompt                    	Ask command-line with Prompt
 Can use "tmp:Name" file to store temporary objects between multiple commands...
  -res "tmp:Name1" 16384  	Reserve size on temporary object
       (tmp objects cannot grow on -append unless reserved)
  name="value" -- set variable that can be later used $name.cer ...
                  name must be simple (chars and digits), value may be quoted
  -md5 file               	Print MD5 of file
  -sha file  -sha256 file 	Print MD5 of file
  -mdsh file              	Print MD5+SHA1 of file