c# Pad at the leading octets - c#

i have exponent whats 3 bytes long. Now i need it to be 4 bytes. I found somewhere that i could pad at the leading octets.. but i have no idea to do that.. So can anybody help me out?
Example Input: exponent what i have right now is 65537, int bytes its then 01 00 01.

Assuming you just want to pad it with zeroes, create a new four byte array and copy the existing one into it:
byte[] newArray = new byte[4];
// Copy bytes 0, 1, 2 of oldArray into 1, 2, 3 of newArray.
Array.Copy(oldArray, 0, newArray, 1, 3);
(You can do this manually with three assignments as well; that's potentially simpler for this situation, but doesn't scale well (in terms of code) to larger sizes.)
Change the "1" to "0" if you find you need the padding at the end instead of the start... or use Array.Resize in that case.

Not entirely sure of the meaning, but it sounds like you just want:
byte[] first = /* 3 bytes */
byte[] second = new byte[4];
// since 3 bytes, we'll do this manually; note second[0] is 0 already
second[1] = first[0];
second[2] = first[1];
second[3] = first[2];
Of course, if you are actually dealing with an int it is already padded on the left with 0, to 4 bytes.

Related

Combine two byte arrays of variable length through bit shifting

I have two byte arrays, they have variable length but always add up to 8 bytes. These need to be combined into a long. I can do this with creating a byte array and copying the required data. But I was thinking that this should also be possible through bit-shifting. I've been trying this (simplified with just one length):
var bytes1 = new byte[] { 1, 2, 3, 4, 5, 6, 7 };
var bytes2 = new byte[] { 8 };
unsafe
{
fixed (byte* b1 = bytes1)
{
fixed (byte* b2 = bytes2)
{
ulong* bl1 = (ulong*)b1;
ulong v = (*bl1<< 8) | (*b2);
var bytes = bytes1.Concat(bytes2).ToArray();
// These two are different:
Console.WriteLine(v);
Console.WriteLine(BitConverter.ToUInt64(bytes, 0));
}
}
}
I'm aware that Concat works, but I'd like to this to work too.
First of all, (ulong*)b1 is an out of bounds read because the array has length 7 and sizeof(ulong) == 8. The next read is also broken in that way. Alignment is also a problem. I don't see a way to rescue that approach. You could read 4 bytes, then 2 bytes, then 1 byte if you really are looking for performance.
I'd loop over the arrays and shift in each byte:
ulong result = 0;
void MergeArray(byte[] bytes) {
foreach (var b in bytes) {
result = result << 8 | (ulong)b;
}
}
MergeArray(bytes1);
MergeArray(bytes2);
Using a local function for code sharing.
You can improve performance by taking 4 bytes as the first chunk if the array length supports a read of that size. Then, fetch 2, then fetch 1. That way there is not even a loop and the number of operations is minimized.
Whether this is good or not depends on your need for performance which must be traded off with code legibility.

Function to XOR two 128 bits. How do I generate 128 bit values?

I'm trying to learn simple cryptology and as a starter I'm trying to achieve the following.
A function, taking two 128 bit params (key and plaintext) as input and returning their XOR. I know XOR is not safe but I'm starting out with a simple example.
This is what I have tried:
class Program
static void Main(string[] args)
{
string key = "B25829846AED8"; //128 bits??
string plaintext = "A9BB51625ECBE"; //128 bits??
//Convert key to byte array
byte[] keyBytes = new byte[key.Length * sizeof(char)];
System.Buffer.BlockCopy(key.ToCharArray(), 0, keyBytes, 0, keyBytes.Length);
//Convert plaintext to byte array
byte[] plaintextBytes = new byte[plaintext.Length * sizeof(char)];
System.Buffer.BlockCopy(plaintext.ToCharArray(), 0, plaintextBytes, 0, plaintextBytes.Length);
//Encrypt (XOR)
string result = new Encrypter().encrypt(keyBytes, plaintextBytes);
}
}
Encrypter.cs :
class Encrypter
{
public string encrypt(byte[] key, byte[] plaintext)
{
BitArray keyBits = new BitArray(key);
BitArray plaintextBits = new BitArray(plaintext);
if(keyBits.Length == plaintextBits.Length)
{
BitArray result = keyBits.Xor(plaintextBits);
return result.ToString();
}
return null;
}
}
My problem:
I'm struggling with what to put as the key and plaintext. How can I ensure that the values are exactly 128 bit each?
E.g. B25829846AED8 is apparently a 128 bit WEP key. If I assign this to my key variable and when I enter the encrypt method the keyBits.Length property has the value 208. This is what I don't get. Also the parameter key has the length 26, which I'm also confused by.
Why is the key-length 26?
C#-strings is in unicode, so you can write all characters out there eg. Chinese, Japanese, etc. etc. That takes two bytes (in utf-16). 13*2=26.
Is your wep-key 128 bits
You've got a key for 128 bit wep-protocoll which is using 104 bit keys. (fun times) Wiki on Wep
But as far as I understand you're not trying to implement wep, you're trying to encode something. Take two random integers translate them to bytes and put them after each other. BAM- 128 bits :)
using System.Linq
byte[] key = BitConverter.GetBytes(25).Concat(BitConverter.GetBytes(284)) ;
Other than that you seam to have it under control, good luck :)
You want to use 128 bit keys or in other words 16 bytes. Strings are made of chars and the char datatype in C# is uses 2 bytes (16 bits). So you could make a 16 byte key from strings of length 8, which is sort of problematic because it is difficult to use the full 128bit range due to unprintable characters and so on. It would be way easier to represent the key as a byte array with length 16 from the start for example: byte[] key = {1, 8, 255, 12, 2, 1, 1, 1, 1, 1, 1, 2, 3, 4, 5, 5};
You say that B25829846AED8 is a 128bit key. Interpreted as a string this is not true: 13 chars = 26 bytes = 208 bit so that is the explanation for your result. Interpreting each character as a hexadecimal digit this key would be 13*4 = 52bit. Interpreting each character as a ANSI character (size 8bit) would be 13*8 = 104 bit.
So to produce the byte array for the key from a string or number you have to define how you interpret the string or number. As already said above, easiest would be to enter 16 bytes directly.

Read Specific Bytes Out of Byte Array C#

I am a newbie with a question regarding reading specific bytes out of an array in C#. I received an array response that is 128 bytes long and I am looking to read and store the first 4 bytes of the array. How do I do so?
I've read a number of posts about shifting bytes but was a bit confused and I am looking to get going in the right direction.
Use one of the Array.Copy overloads:
byte[] bytes = new byte[4];
Array.Copy(originalArray, bytes, bytes.Length);
Use Array.Copy method:
// your original array
var sourceArray = new byte[128];
// create a new one with the size you need
var firstBytes = new byte[4];
// copy the required number of bytes.
Array.Copy(sourceArray, 0, firstBytes, 0, firstBytes.Length);
If you do not need the rest of the data in the original array, you can also resize it, truncating everything after the first 4 bytes:
Array.Resize(ref sourceArray, 4);
Read the first 4 bytes in 4 different variables:
byte first = array[0],
second = array[1],
third = array[2],
forth = array[4];
Read them as one 32-bit long integer:
int result =
first << 24 ||
second << 16 ||
third << 8 ||
forth;
The x << n operator shifts the bits of number x, n times to the left. You are effectively moving the bytes of first 24 positions to the left, thus first will be stored in bits with indices 24 to 31 like that:
first 00000000 00000000 00000000
Next, move second 16 positions to the left, thus storing it in bits 16 to 23 and so on:
first second 00000000 00000000
Wikipedia provides a good summary of bitwise operations if you need more details.
Example from a network stream.
byte[] bytesRead = 0;
using (NetworkStream stream = client.GetStream())
{
byte[] length = new byte[4];
bytesRead = stream.Read(length, 0, 4);
}
bytesRead contains the first 4 bytes stored in the networkstream.
You could use the Take method. Although, this is only available if you are using .NET 3.5 or later. You will need to have using System.Linq; at the top of the .cs file.
var bytes = originalArray.Take(4).ToArray();

get every nth byte/value in array

I'm looking for a smooth/fast way to retrieve every nth short in a byte array and copy it to a new array.
l = lowerbyte
u = upperbyte
My data is of the following form:
byte[] bytes= {a0l, a0u, b0l, b0u, c0l, ..., n0l, n0l, a1l, a1u, b1l, ..., nXl, nXu}
What I need is to get get n byte arrays of length X (e.g., a[0..X], b[0..X], ... or M[a..n][0..X])
I was thinking of the following two steps:
convert values to short (=> short[] shorts= { a0, b0, c0, ... n0, a1, .. nX})
by using something like
short[] shorts= new short[(int)(Math.Ceiling(bytes.Length / 2.0)];
Buffer.BlockCopy(bytes, 0, shorts, 0, bytes.Length);
retrieve every second value from shorts
I'm looking for some fast code here... something like blockcopy with skip
I am completely aware that I could use a loop - but maybe there's a better
solution to it as I need to do this task for 80MB/s...
convert it back to byte arrays (same same - using blockcopy)
byte[] arrayX = new byte[shorts.Length * 2];
Buffer.BlockCopy(shorts, 0, arrayX , 0, arrayX .Length);
Thank you so much!
I think you might as just well copy the bytes directly to the new byte array, having calculated the correct offset for each short.
Converting it all to a separate short array and back to a byte array is a waste of time IMO.

How to produce 8 bytes from 4 bytes with a reproducible operation?

I've 4 bytes of data and need an 8 bytes array for a security operation. I should produce these 8 bytes form the 4 bytes byte array and this should be reproducible.
I was thinking of using exact byte array and adding 4 extra bytes and fill them with AND, OR, XOR... of the initial array in a known sequence. I'm not sure if it's a good idea. I just need an 8 byte array from this 4 bytes and the operation should be reproducible (same 8 bytes with same given 4 bytes). Please give an example in C#
Why not just pad the existing 4 bytes with another 4 bytes of zeroes? Or repeat the original 4 bytes. For example:
static byte[] Pad(byte[] input)
{
// Alternatively use Array.Resize
byte[] output = new byte[input.Length + 4];
Buffer.BlockCopy(input, 0, output, 0, input.Length);
return output;
}
static byte[] Repeat(byte[] input)
{
byte[] output = new byte[input.Length * 2];
Buffer.BlockCopy(input, 0, output, 0, input.Length);
Buffer.BlockCopy(input, 0, output, input.Length, input.Length);
return output;
}
Both of these fulfil your original criteria, I believe... but I suspect you're looking for something else. If that's the case, you need to be explicit about what you need.
EDIT: As I've said in the comments, you're basically not adding any real security here - padding will make that clearer, IMO. On the other hand, if you do want some security-through-obscurity, you could find a random number generator that allows seeding, and use that as a starting point. For example:
// Don't use this - see below. Just the concept...
int seed = BitConverter.ToInt32(input, 0); // TODO: Cope with endianness
Random rng = new Random(seed);
byte[] output = new byte[8];
Buffer.BlockCopy(input, 0, output, 0, 4);
for (int i = 4; i < 8; i++) {
output[i] = (byte) rng.Next(256);
}
Now, the reason I've got the comment above is that you probably need an algorithm which is guaranteed not to change between versions of .NET. Find code to something like the Mersenne Twister, for exmaple.
There are multiple methods of doing padding for block ciphers.
This Wikipedia article covers some of the more accepted solutions: http://en.wikipedia.org/wiki/Padding_(cryptography)#Padding_methods
Barring any other considerations, I would use PKCS#7 padding.
How about
bytes.Concat(bytes)
I would be very careful. If a security operation requires 64 bits worth of data it is probably because it requires that much data. If you create your 64 bits from 32 bits with a known reproducible formula you will still only have 32 bits worth of data.
If the security is not affected by the data you have you can just fill the the remaining four bytes with ones or zeros. But you should really try to get 8 bytes of "real" data.

Categories