How to recreate TpmPublic instance from result of TpmPublic.GetTpm2BRepresentation() - c#

I am able to store the endorsement key from a TPM in a byte array using the following code (referencing TSS.NET):
TpmPublic ekPub = GetEndorsementKey();
byte[] ek = ekPub.GetTpm2BRepresentation();
I have tried this, but I don't know how to get from a Tpm2bPublicKeyRsa instance to an instance of TpmPublic:
Tpm2bPublicKeyRsa temp = new Tpm2bPublicKeyRsa(ek)
Notes:
I want to pass the endorsement key around as a byte array because it's convenient to Base64 encode the array for copy/paste.
I want to get back to an instance of TpmPublic so that I can transform that key (like this) into something I can use it server side in .NET (without a TPM) .

The solution I came up with was to use the GetTpmRepresentation method:
TpmPublic ekPub = GetEndorsementKey();
byte[] ekPubBytes = ekPub.GetTpmRepresentation();
That makes it easy to get the TpmPublic instance back using the marshaller:
var mashaller = new Marshaller(ekPubBytes);
TpmPublic ekPub = m.Get<TpmPublic>();

Related

How can I create a byte (array) from a string?

how can I create a byte data type from a string? For example: The device I am sending data to, expects the data to be in the hexadecimal format. More specifically, it needs to be in the format: 0x{hexa_decimal_value}
Hard coded, it already worked sending data this way.
I would create a byte array like this:
byte[] items_to_send_ = new byte[] {0x46, 0x30, 0x00};
Now I want to code it dynamically.
The code I am now trying to write looks like this:
var ListByte = new List<byte>();
foreach (char val in messageToConvert)
{
var hexa_decimal_val = Convert.ToInt32(val).ToString("X");
hexa_decimal_val = $"0x:{hexa_decimal_val}";
byte val_ = CreateByteFromStringFunction(hexa_decimal_val); // How?
ListByte.Add(val_);
}
The step in question is when creating the variable val_, where I want to build the byte value from hexa_decimal_val, but I just don't know how. Casting does not work, and I did not find any other function that would do it for me.
It feels like there should be a really easy solution to this, but I just don't seem to find it.
What makes looking for the correct answer tricky here is that I already know how to convert from string to hexadecimal value, but the conversion afterwards is nowhere to be found.
You don't need to do create bytes from characters one by one and append to a list. You can usethis;
var encodedByteList = Encoding.UTF8.GetBytes(messageToConvert);
If you still want to do that, you can do something like this;
var encodedByteList = new List<byte>();
foreach (var character in messageToConvert)
{
var correspondingByte = (byte)character;
encodedByteList.Add(correspondingByte);
}
Or with LINQ, you can use this one liner;
var encodedByteList = messageToConvert.Select(c => (byte)c);

Difference between HMACSHA512 constructor and factory

Why does this returns a hash size of 512 bit ...
var text = "Hello World";
var buffer = Encoding.UTF8.GetBytes(text);
var hmac = new System.Security.Cryptography.HMACSHA512();
hmac.Key = GetRandomBits(512);
hmac.ComputeHash(buffer);
Assert.That(hmac.HashSize, Is.EqualTo(512));
... and this a hash size of 160 bit?
var text = "Hello World";
var buffer = Encoding.UTF8.GetBytes(text);
var hmac = System.Security.Cryptography.HMACSHA512.Create();
hmac.Key = GetRandomBits(512);
hmac.ComputeHash(buffer);
Assert.That(hmac.HashSize, Is.EqualTo(512)); // failure
The constructor and the factory are both related to HMACSHA512, so I assumend the same output.
There is no HMACSHA512.Create(). You're actually calling HMAC.Create() (because the language allows writing calls to static methods off of derived types)
So you're just getting "an HMAC", which seems to be HMACSHA1.
It looks to me like the Create factory method is not doing HMACSHA512 when used in this way.
The documentation breaks it down for us.
Return Value Type: System.Security.Cryptography.HMAC A new SHA-1
instance, unless the default settings have been changed by using the
element.
So it looks like the reason they are different in size is because the Create Method is returning a SHA-1 instance instead of the HMACSHA512 instance as you expected.

What is the .NET System.Numerics.BigInteger Equivalent of Org.BouncyCastle.Math.BigInteger.ToByteArrayUnsigned?

I am currently working with the .NET port of BouncyCastle and I am having some trouble converting a big integer into a System.Guid using the native .NET BigInteger.
For some context, I am using BouncyCastle in one ("source") application to convert a System.Guid to a Org.BouncyCastle.Math.BigInteger. This value is then saved as a string in the format 3A2B847A960F0E4A8D49BD62DDB6EB38.
Then, in another ("destination") application, I am taking this saved string value of a BigInteger and am trying to convert it back into a System.Guid.
Please note that in the destination application I do not want BouncyCastle as a reference and would like to use core .NET libraries for the conversion. However, since I am running into problems converting with core .NET classes, I am using BouncyCastle and the following code does exactly what I would like:
var data = "3A2B847A960F0E4A8D49BD62DDB6EB38";
var integer = new Org.BouncyCastle.Math.BigInteger( data, 16 );
var bytes = integer.ToByteArrayUnsigned();
var guid = new Guid( bytes ); // holds expected value: (7A842B3A-0F96-4A0E-8D49-BD62DDB6EB38)
As you can see, there is a ToByteArrayUnsigned method on the Org.BouncyCastle.Math.BigInteger that makes this work. If I use the ToByteArray on the System.Numerics.BigInteger (even when resizing the array as discussed in this question) it does not work and I get a different System.Guid than expected.
So, what is the best way to perform the equivalent to the above operation using native .NET classes?
Solution
Thanks to #John-Tasler's suggestion, it turns out this was due to endianess... darn you endianess... will your endiness ever end? :P
var parsed = System.Numerics.BigInteger.Parse( "3A2B847A960F0E4A8D49BD62DDB6EB38", NumberStyles.HexNumber ).ToByteArray();
Array.Resize( ref parsed, 16 );
var guid = new Guid( parsed.Reverse().ToArray() ); // Hoorrrrayyyy!
What's the actual value of the resulting Guid when using .NET's BigIntegrer?
It could be that the two implementations are just storing the bytes differently. Endianess, etc.
To see what comes back from each implementation's array of bytes:
var sb = new StringBuilder();
foreach (var b in bytes)
{
sb.AppendFormat("{0:X2} ", b);
}
sb.ToString();
It'd be an interesting comparison.
I would avoid BigInteger here entirely. Your data bytes are already in the correct order so you can convert to byte[] directly.
var data = "3A2B847A960F0E4A8D49BD62DDB6EB38";
var bytes = new byte[16];
for (var i = 0; i < 16; i++)
bytes[i] = byte.Parse(data.Substring(i * 2, 2), NumberStyles.HexNumber);
var guid = new Guid(bytes); // 7a842b3a-0f96-4a0e-8d49-bd62ddb6eb38

xxHash convert resulting in hash too long

I'm using xxHash for C# to hash a value for consistency.
ComputeHash returns a byte[], but I need to store the results in a long.
I'm able to convert the results into an int32 using the BitConverter. Here is what I've tried:
var xxHash = new System.Data.HashFunction.xxHash();
byte[] hashedValue = xxHash.ComputeHash(Encoding.UTF8.GetBytes(valueItem));
long value = BitConverter.ToInt64(hashedValue, 0);
When I use int this works fine, but when I change to ToInt64 it fails.
Here's the exception I get:
Destination array is not long enough to copy all the items in the collection. Check array index and length.
When you construct your xxHash object, you need to supply a hashsize:
var hasher = new xxHash(32);
valid hash sizes are 32 and 64.
See https://github.com/brandondahler/Data.HashFunction/blob/master/src/xxHash/xxHash.cs for the source.
Adding a new answer because current implementation of xxHash from Brandon Dahler uses a hashing factory where you initialize the factory with a configuration containing hashsize and seed:
using System.Data.HashFunction.xxHash;
//can also set seed here, (ulong) Seed=234567
xxHashConfig config = new xxHashConfig() { HashSizeInBits = 64 };
var factory = xxHashFactory.Instance.Create(config);
byte[] hashedValue = factory.ComputeHash(Encoding.UTF8.GetBytes(valueItem)).Hash;
BitConverter.ToInt64 expects hashedValue to have 8 bytes (= 64bits). You could manually extend, and then pass it.

Weird behaviour of MD5 hashing

I have faced aweird problem with the following code, the code below suppose to stop after one iteration, but it just keep going. However, if I remove the last "result_bytes = md5.ComputeHash(orig_bytes);" then it will work. Does anyone face similar problem before?
MD5 md5;
byte[] orig_bytes;
byte[] result_bytes;
Dictionary<byte[], string> hashes = new Dictionary<byte[], string>();
string input = "NEW YORK";
result_bytes = UnicodeEncoding.Default.GetBytes("HELLO");
while (!hashes.ContainsKey(result_bytes))
{
md5 = new MD5CryptoServiceProvider();
orig_bytes = UnicodeEncoding.Default.GetBytes(input);
result_bytes = md5.ComputeHash(orig_bytes);
hashes.Add(result_bytes, input);
Console.WriteLine(BitConverter.ToString(result_bytes));
Console.WriteLine(hashes.ContainsKey(result_bytes));
result_bytes = md5.ComputeHash(orig_bytes);
}
When you reassign result_bytes to a new value in the last line, you have a new reference to a byte array, which is not equal to the one in the collection, therefore hashes.ContainsKey returns false.
You're assuming that byte arrays override Equals and GetHashCode to compare for equality: they don't. They just use the default identity test - so without the extra assignment at the end, you're just checking whether the exact key object you've just added is still in the dictionary - which of course it is.
One way round this would be to store a reversible string representation of the hash (e.g. using base64), instead of the hash itself. Or write your own implementation of IEqualityComparer<byte[]> and pass that to the Dictionary constructor, so that it uses that implementation to find the hash code of byte arrays and compare them with each other.
In short: this has nothing to do with MD5, and everything to do with the fact that
Console.WriteLine(new byte[0].Equals(new byte[0]));
will print False :)

Categories

Resources