Contents
Manually verify PKCS#7 self signed data OpenSSL
Steps to encrypt and verify:
1.Generate certificate and private key:
openssl req -x509 -newkey rsa:1024 -keyout keyfile.key -out certificate.cer -nodes -subj “/CN=testcert”
Here ,
openssl req : certificate request and certificate generating utility.
-x509
this option outputs a self signed certificate instead of a certificate request. This is typically used to generate a test certificate or a self signed root CA. The extensions added to the certificate (if any) are specified in the configuration file.
–newkey arg
this option creates a new certificate request and a new private key. The argument takes one of several forms. rsa:nbits, where nbits is the number of bits, generates an RSA key nbits in size. If nbits is omitted, i.e. -newkey rsa specified, the default key size, specified in the configuration file is used.
-keyout filename
this gives the filename to write the newly created private key to. If this option is not specified then the filename present in the configuration file is used.
-out filename
This specifies the output filename to write to or standard output by default.
-nodes
if this option is specified then if a private key is created it will not be encrypted.
-subj arg
sets subject name for new request or supersedes the subject name when processing a request. The arg must be formatted as /type0=value0/type1=value1/type2=…, characters may be escaped by \ (backslash), no spaces are skipped.
Here ,
2. Write following text to a sample file:
echo “Alice still in wonderland” > data.txt
3. Self-signing data file:
openssl smime -sign -md sha1 -binary -in data.txt -out data.txt.signed -outform der -inkey keyfile.key -signer certificate.cer
Here ,
openssl smime : It can encrypt, decrypt, sign and verify S/MIME messages.
-sign
sign file “data.txt” using the supplied certificate (certificate.cer)and private key(keyfile.key). Input file(“data.txt”) is the message to be signed. The signed message in MIME format is written to the output file(“data.txt.signed”).
-md sha1
digest algorithm to use when signing or resigning. If not present then the default digest algorithm for the signing key will be used . Here algorithm used will be “sha1”
-outform SMIME|PEM|DER
this specifies the output format for the PKCS#7 structure. The default is SMIME which write an S/MIME format message. PEM and DER format change this to write PEM and DER format PKCS#7 structures instead. This currently only affects the output format of the PKCS#7 structure, if no PKCS#7 structure is being output (for example with -verify or -decrypt) this option has no effect.
4. openssl x509 -inform pem -in certificate.cer -noout -pubkey > pubkey.pem
(dd if=data.txt.signed of=signed-sha1.bin bs=1 skip=$[ 850 + 3 ] count=128)
x509 – Certificate display and signing utility
-inform DER|PEM|NET
This specifies the input format normally the command will expect an X509 certificate but this can change if other options such as -req are present. The DER format is the DER encoding of the certificate and PEM is the base64 encoding of the DER encoding with header and footer lines added.
-in filename
This specifies the input filename to read a certificate from
-noout
this option prevents output of the encoded version of the request.
-pubkey
outputs the certificate’s SubjectPublicKeyInfo block in PEM format.
5. openssl rsautl -verify -pubin -inkey pubkey.pem < signed-sha1.bin > verified.bin
rsautl The rsautl command can be used to sign, verify, encrypt and decrypt data using the RSA algorithm.
-verify
verify the input data and output the recovered data.
-pubin
the input file is an RSA public key.
-inkey file
the input key file, by default it should be an RSA private key.
6. openssl asn1parse -inform der -in verified.bin
// Results in the hash of the signed attributes
For reference, in my case: 82C9772D39C0943A3BF0EA131055219DAEE5FE2F
7.Find the offset and length of the signed attributes
openssl asn1parse -inform der -in data.txt.signed -i
564:d=4 hl=4 l= 413 cons: SEQUENCE
568:d=5 hl=2 l= 1 prim: INTEGER :01
571:d=5 hl=2 l= 32 cons: SEQUENCE
573:d=6 hl=2 l= 19 cons: SEQUENCE
575:d=7 hl=2 l= 17 cons: SET
577:d=8 hl=2 l= 15 cons: SEQUENCE
579:d=9 hl=2 l= 3 prim: OBJECT :commonName
584:d=9 hl=2 l= 8 prim: UTF8STRING :testcert
594:d=6 hl=2 l= 9 prim: INTEGER :DF6A0ED03F978DE4
605:d=5 hl=2 l= 9 cons: SEQUENCE
607:d=6 hl=2 l= 5 prim: OBJECT :sha1
614:d=6 hl=2 l= 0 prim: NULL
616:d=5 hl=3 l= 216 cons: cont [ 0 ]
-i
indents the output according to the “depth” of the structures.
8. Extract the signed attributes, it’s the cont[0] in the SignerInfo, just after the certificate:
dd if=data.txt.signed of=signed-attribs.bin bs=1 skip=616 count=$[ 3 + 216 ]
9. Change the ASN.1 SEQUENCE to a SET by changing the first byte to 0x31
echo -ne “\x31” | dd conv=notrunc bs=1 count=1 of=signed-attribs.bin
10. Hash the signed attributes, the result can be compared to the hash from 6.
Thereby verifying the signed attributes are signed by the public key provided in 5.
However, this doesn’t verify the actual data!!
sha1sum signed-attribs.bin
11. Note the hash from the signed attributes, run the command from 7. again and look for something like this
675:d=6 hl=2 l= 35 cons: SEQUENCE
677:d=7 hl=2 l= 9 prim: OBJECT :messageDigest
688:d=7 hl=2 l= 22 cons: SET
690:d=8 hl=2 l= 20 prim: OCTET STRING [HEX DUMP]:07D30079798D71F28813C16419166FC0CBA35BE6
12. Verify the message digest of the actual data
sha1sum data.txt
07d30079798d71f28813c16419166fc0cba35be6 *data.txt
Encrypt/Decrypt string in C#
public static string Encrypt(string data)
{
try
{
byte[] encData_byte = new byte[data.Length];
encData_byte = Encoding.UTF8.GetBytes(data);
string encodedData = Convert.ToBase64String(encData_byte);
return encodedData;
}
catch (Exception e)
{
CLogger.WriteLog(ELogLevel.ERROR, “Exception: ” + e.ToString());
throw new Exception(“Error in base64Encode ” + e.Message);
}
}
public static string Decrypt(string data)
{
try
{
UTF8Encoding encoder = new UTF8Encoding();
Decoder utf8Decode = encoder.GetDecoder();
byte[] todecode_byte = Convert.FromBase64String(data);
int charCount = utf8Decode.GetCharCount(todecode_byte, 0, todecode_byte.Length);
char[] decoded_char = new char[charCount];
utf8Decode.GetChars(todecode_byte, 0, todecode_byte.Length, decoded_char, 0);
string result = new String(decoded_char);
return result;
}
catch (Exception e)
{
CLogger.WriteLog(ELogLevel.ERROR, “Exception: ” + e.ToString());
throw new Exception(“Error in base64Decode ” + e.Message);
}
}
Resolving technical problems:
Solve your technical problems instantly
We provide Remote Technical Support from Monday to Sunday, 7:00PM to 1:00 AM
Mail your problem details at [email protected] along with your mobile numberand we will give you a call for further details. We usually attend your problems within 60 minutes and solve it in maximum 2 days.