This page expands the manual page Using output in XML documents and gives some sample code.
You can use CryptoSys PKI Pro to create most of the cryptographic elements required in the [XML-DSIG] and [XML-ENC] specifications to insert into XML documents.
In general, work using byte arrays and then use
CNV_B64StrFromBytes
or
Cnv.ToBase64
to convert byte arrays into base64 encoding.
Here is a selection of some elements you can create. The test files are in pki_pro_files.zip (7 kB).
DigestValue | SignatureValue | X509Certificate | X509IssuerSerial | X509IssuerName | X509SubjectName | RSAKeyValue | RSAKeyPair | CipherValue | References | Contact us
DigestValue
elementUse
Hash.BytesFromBytes
or
Hash.BytesFromFile
then
Cnv.ToBase64
.
// Compute sha1 digest value of canonicalized object // NB You must do your own canonicalization! string digval = Cnv.ToBase64(Hash.BytesFromFile("xmldsig-object-c14n.txt", HashAlgorithm.Sha1)); Console.WriteLine("<DigestValue>" + digval + "</DigestValue>");
<DigestValue>OPnpF/ZNLDxJ/I+1F3iHhlmSwgo=</DigestValue>
SignatureValue
element
Use
Sig.SignData
or
Sig.SignFile
.
// Compute rsa-sha1 signature value of c14n'd signed-info element using Alice's private key string sigval = Sig.SignFile("xmldsig-signedinfo-c14.txt", "alice.key", "password", SigAlgorithm.Rsa_Sha1); Console.WriteLine("SignatureValue: " + sigval);
SignatureValue: nihUFQg4mDhLgecvhIcKb9Gz8VRTOlw+adiZOBBXgK4JodEe5aFfCqm8WcRIT8GL LXSk8PsUP4//SsKqUBQkpotcAqQAhtz2v9kCWdoUDnAOtFZkd/CnsZ1sge0ndha40wWDV+nOWyJxkYgi cvB8POYtSmldLLepPGMz+J7/Uws=
Alternatively, use
Rsa.EncodeMsgForSignature
followed by
Rsa.RawPrivate
then
Cnv.ToBase64
.
X509Certificate
element// Create X509Certificate element string s = X509.ReadStringFromFile("smallca.cer"); Console.WriteLine("X509Certificate:\n" + s);
X509Certificate: MIHgMIGaAgEBMA0GCSqGSIb3DQEBBQUAMAwxCjAIBgNVBAMTAUEwHhcNOTkwOTE5MDEwODQ3WhcNMzkx MjMxMjM1OTU5WjAMMQowCAYDVQQDEwFBMEowDQYJKoZIhvcNAQEBBQADOQAwNgIxAvkJan2DVcJxrvFq y0VBurMiooO1rd5w4zcZp8m77nZL4vy4XMeb4j8nH2+3tTaAGQIBAzANBgkqhkiG9w0BAQUFAAMyAAGa m7Lsuc39ZsaUWy7Wltwyh2jaXm8uXVp/5gkuYI+MRaUYfgYc6YGq6tby4xR9JZE=
X509IssuerSerial
elementUse
X509.QueryCert
with query "serialNumber"
and
X509.Options.Decimal
.
// Create X509IssuerSerial element string cerFile = "alice.cer"; string s = X509.QueryCert(cerFile, "serialNumber", X509.Options.Decimal); Console.WriteLine("X509IssuerSerial: " + s);
X509IssuerSerial: 93318145165434344057210696409401045936
X509IssuerName
elementUse
X509.QueryCert
with query "issuerName"
and
X509.Options.Ldap
.
// Create X509IssuerName element string s = X509.QueryCert(cerFile, "IssuerName", X509.Options.Ldap); Console.WriteLine("X509IssuerName: " + s);
X509IssuerName: CN=CarlRSA
X509SubjectName
elementUse
X509.QueryCert
with query "subjectName"
and
X509.Options.Ldap
.
// Create X509SubjectName element string s = X509.QueryCert(cerFile, "subjectName", X509.Options.Ldap); Console.WriteLine("X509SubjectName: " + s);
X509SubjectName: CN=AliceRSA
RSAKeyValue
element
Use
Rsa.KeyValue
or
Rsa.ToXMLString
.
// Create RSAKeyValue element (the public key) string pubkey = Rsa.ReadPublicKey("alice.cer").ToString(); s = Rsa.KeyValue(pubkey, "Modulus"); Console.WriteLine("RSAKeyValue Modulus: " + s); s = Rsa.KeyValue(pubkey, "Exponent"); Console.WriteLine("RSAKeyValue Exponent: " + s);
RSAKeyValue Modulus: 4IlzOY3Y9fXoh3Y5f06wBbtTg94Pt6vcfcd1KQ0FLm0S36aGJtTSb6pYKfy X7PqCUQ8wgL6xUJ5GRPEsu9gyz8ZobwfZsGCsvu40CWoT9fcFBZPfXro1Vtlh/xl/yYHm+Gzqh0Bw76x tLHSfLfpVOrmZdwKmSFKMTvNXOFd0V18= RSAKeyValue Exponent: AQAB
RSAKeyPair
element
Use
Rsa.ToXMLString
.
// Create RSAKeyPair element (the full private key) string prikey = Rsa.ReadPrivateKey("alice.key", "password").ToString(); s = Rsa.ToXMLString(prikey, 0); Console.WriteLine("RSAKeyPair:\n" + s);
RSAKeyPair: <RSAKeyPair><Modulus>4IlzOY3Y9fXoh3Y5f06wBbtTg94Pt6vcfcd1KQ0FLm0S36aGJtTSb6pYKfy X7PqCUQ8wgL6xUJ5GRPEsu9gyz8ZobwfZsGCsvu40CWoT9fcFBZPfXro1Vtlh/xl/yYHm+Gzqh0Bw76x tLHSfLfpVOrmZdwKmSFKMTvNXOFd0V18=</Modulus><Exponent>AQAB</Exponent><P>9tbgIiFMX wpw/yf85bNQap3lD7WFlsZA+qgKtJubDFXCAR35N4KKFMjykw6SzaVmIbk80ga/tFUxydytypgt0Q==< /P><Q>6N6wESUJ0gJRAd6K6JhQ9Xd3YaRFk2sIVZZzXfTIWxKTInOLf9Nwf/Wkqrt0/Twiato4kSqGW2 wU6K5MnvqOLw==</Q><DP>l0zwh5sXf+4bgxsUtgtqkF+GJ1Hht6B/9eSI41m5+R6b0yl3OCJI1yKxJZ i6PVlTt/oeILLIURYjdZNR56vN8Q==</DP><DQ>LPAkW/qgzYUi6tBuT/pszSHTyOTxhERIZHPXKY9+R ozsFd7kUbOU5yyZLVVleyTqo2IfPmxNZ0ERO+G+6YMCgw==</DQ><InverseQ>WIjZoVA4hGqrA7y730 v0nG+4tCol+/bkBS9u4oiJIW9LJZ7Qq1CTyr9AcewhJcV/+wLpIZa4M83ixpXub41fKA==</InverseQ ><D>pAPDJ0d2NDRspoa1eUkBSy6K0shissfXSAlqi5H3NvJ11ujNFZBgJzFHNWRNlc1nY860n1asLzdu HO4Ovygt9DmQbzTYbghb1WVq2EHzE9ctOV7+M8v/KeQDCz0Foo+38Y6idjeweVfTLyvehwYifQRmXskb r4saw+yRRKt/IQ==</D></RSAKeyPair>
CipherValue
element
xmlenc#rsa-1_5:
Use
Rsa.EncodeMsgForEncryption
with Rsa.EME.PKCSv1_5
option
followed by
Rsa.RawPublic
then
Cnv.ToBase64
// Content encryption key to be transported byte[] cek = Cnv.FromHex("737C791F25EAD0E04629254352F7DC6291E5CB26917ADA32"); // Read in recipient's public key to ephemeral "internal" string string pubkey = Rsa.ReadPublicKey("bob.cer").ToString(); // Get required size of encryption block int nbytes = Rsa.KeyBytes(pubkey); // Encode the message for encryption byte[] block = Rsa.EncodeMsgForEncryption(nbytes, cek, Rsa.EME.PKCSv1_5); // Encrypt with RSA key block = Rsa.RawPublic(block, pubkey); // Output encoded in base64 Console.WriteLine("xmlenc#rsa-1_5\nCipherValue: " + Cnv.ToBase64(block));
xmlenc#rsa-1_5 CipherValue: QPkP6v10fbcR8ly9d+pLop/Aszjxop9XoiKuYZmm5bfNfc0GUdhpnHkpGEEEkRrBgN0 hV0vd+zKlv/T3s+HMtm6aTwI790MKwA0VO/4QafLvf6Nh6igZlvsrJXuSiPnuige/oQ/RPA89Ml3Py+r q10RahNu+32kXJPsgwi0ntWs=
xmlenc#rsa-oaep-mgf1p:
As for xmlenc#rsa-1_5
except use
Rsa.EME.OAEP
option.
xmlenc#tripledes-cbc: Use
Cipher.Encrypt
with options
CipherAlgorithm.Tdea
,
Mode.CBC
and
Padding.Pkcs5
,
then use
Cnv.ToBase64
after prepending the IV to the ciphertext.
// Content to be encrypted (From S/MIME Examples) byte[] msg = Encoding.ASCII.GetBytes("This some sampe content."); // 192-bit tripledes key byte[] cek = Cnv.FromHex("737C791F25EAD0E04629254352F7DC6291E5CB26917ADA32"); // Initialization vector byte[] iv = Cnv.FromHex("B36B6BFB6231084E"); // Ciphertext = D76FD1178FBD02F84231F5C1D2A2F74A4159482964F675248254223DAF9AF8E4 byte[] ct = Cipher.Encrypt(msg, cek, iv, CipherAlgorithm.Tdea, Mode.CBC, Padding.Pkcs5); // Prepend IV, i.e. concatenate IV + ciphertext // B36B6BFB6231084E || D76FD1178FBD02F84231F5C1D2A2F74A4159482964F675248254223DAF9AF8E4 byte[] value = new byte[iv.Length + ct.Length]; System.Buffer.BlockCopy(iv, 0, value, 0, iv.Length); System.Buffer.BlockCopy(ct, 0, value, iv.Length, ct.Length); // Output encoded in in base64 Console.WriteLine("xmlenc#tripledes-cbc\nCipherValue: " + Cnv.ToBase64(value));
xmlenc#tripledes-cbc CipherValue: s2tr+2IxCE7Xb9EXj70C+EIx9cHSovdKQVlIKWT2dSSCVCI9r5r45A==
Note that the padding for block ciphers described in section 5.2 of XML-ENC is similar to PKCS#5
but also allows arbitrary padding bytes.
PKCS#5 padding is always valid when encrypting, but you may need to use the Padding.NoPad
option when decrypting
and remove the arbitrary padding bytes "by hand".
xmlenc#aes128-cbc:
As for xmlenc#tripledes-cbc
except use
CipherAlgorithm.Aes128
option.
xmlenc#aes192-cbc:
As for xmlenc#tripledes-cbc
except use
CipherAlgorithm.Aes192
option.
xmlenc#aes256-cbc:
As for xmlenc#tripledes-cbc
except use
CipherAlgorithm.Aes256
option.
For more information, please send us a message.
This page last updated 7 December 2019