![]() |
|
|
![]() |
|
|
|
|
RFC3394 Key-wrapping Algorithm in C# This page presents a C# implementation of the RFC 3394 key-wrapping algorithm. The associated assembly provides two simple operations: one to wrap key data, and another to unwrap the key data. This code also includes a fairly comprehensive unit test library which, among other things, ensures that the implementation is verified against the test vectors provided in RFC 3394. Current version: 1.0.0 This library is being managed by me at this development site, hosted by SourceForge.net.
Key wrapping is the process of encapsulating one or more encryption keys using a cryptographic algorithm in concert with a ikey-encryption key. Additional general information on key wrapping is available at Wikipedia. RFC 3394 specifies a symmetric key encapsulation algorithm also known as the AES Key Wrap Specification. As stated in the RFC, it was designed with the following goal in mind:
This algorithm involves a small number of iterations, over which an AES operation, an XOR operation, and a bit of rotation alter the input. The following picture from Wikipedia illustrates the process nicely: ![]() Note that this standard specifically requires AES as the encapsulation mechanism and, therefore, a valid AES key as the key-encryption key.
The attached assembly contains only one public class,
Static methodspublic static byte[] WrapKey(byte[] kek, byte[] plaintext) public static byte[] UnwrapKey(byte[] kek, byte[] ciphertext) Constructorpublic KeyWrapAlgorithm(byte[] kek) Non-static methodspublic byte[] WrapKey(byte[] plaintext) public byte[] UnwrapKey(byte[] ciphertext)
Using the class is straightforward, as most users will only ever need
two lines of code. In the unit tests, I created quick methods to convert
from the hex strings present in the RFC test vectors to
private void StaticWrap(string kek, string pt, string ct, string test) { // Convert hex strings to byte[]s. byte[] key = SoapHexBinary.Parse(kek).Value; byte[] input = SoapHexBinary.Parse(pt).Value; // Static call to the RFC3394 library is here. byte[] output = KeyWrapAlgorithm.WrapKey(key, input); // Verify the test passes. Assert.AreEqual(ct, new SoapHexBinary(output).ToString(), test); } [Test] public void Wrap_128key_128kek_Static() { // Test vectors from RFC3394. string kek = "000102030405060708090A0B0C0D0E0F"; string pt = "00112233445566778899AABBCCDDEEFF"; string ct = "1FA68B0A8112B447AEF34BD8FB5A7B829D3E862371D2CFE5"; // Call the above method to perform the key wrap. StaticWrap(kek, pt, ct, "Wrap_128key_128kek_Static"); }
Using | |||||||||||||||||||||||||||||||||||||||||||||||||||