Torrent Info hash - bittorrent

All magnet links I've found contain a 40-byte(char) info hash.
All tracker announce URI's require a 20-byte(char) hash.
How do these translate? Is this the wrong hash?
My goal is to find a peer, using a magnet link, and download 1 byte of data.

The hash used in BitTorrent is SHA-1 and is 160 bits.
The hash in the magnet link is hex-encoded. ie 4 bits per character. 4*40 = 160 bits.
The hash in the announce is raw binary bytes. ie 8 bits per character. 8*20 = 160 bits.
However, as it's not possible to send all raw binary values in a HTTP-get request, the hash gets URL / %percent-encoded and ends up being longer in a variable length, often more than 40 characters.
To translate: Hex-decode the hash from the magnet link to a raw binary string. Then URL-encode the raw binary string if you need to send it in a HTTP-get request.
A raw binary string is not the same as ASCII or UTF. Make sure to deal with it in a safe way in the programming language you use.

Related

How to perform a digital signature on Smartcard with prestored hash

I am trying to use a smart card to perform a digital signature, my issue is when I try these set of commands:
Select Application: 00A4040410E828BD080F*********
Verify Pin: 0020008506*******
Set SE for CRT HT: 002241AA03800110
Set SE for CRT DST: 002241b606800112840105
Store Hash: 002a90a00890008004AAAAAAAA // AAAAAAAA are Just a random 4 bytes for the card to compute then store
Sign: 002a9e9a00
I can not sign neither by setting the security environment to CRT-DST nor CRT-HT, with the former it returns 6a88(SE problem) and the latter returns 6a95(Hash not found).
I am following IAS_ECC_v1.0.1 to the book but it is not clear which security environment to use in case of setting the hash then signing. I tried the commands for SHA-256 as well but same result.
I am used to setting the security environment then performing the digital signature but this is the first time I encounter the prestored hash type of card.
To clarify at least some issues: What you are describing is not a precomputed hash, but an intermediate hash value, as typically applied in the scheme, where the card has at least some influence in the hash computation. It is supposed to update the given intermediate hash by considering the last data bytes given. This is a sort of middle point between the card hashing all the input data (possible, but due to limited I/O bandwith seldom attractive) and providing the final hash value from the outside (no influence by the card).
Such an intermediate hash requires in DO 90 the intermediate hash value concatenated with a bit counter, which is 8 bytes long. For SHA-256 this would mean 40 bytes (32 bytes hash followed by bit counter). This is combined with DO 80 giving the final data.
Your example (store hash is at least a misleading term), provides the DO 90 as empty, however, contradicting the intention of an intermediate hash.

When deciphering with RC4, what does it mean to skip bytes?

I have the binary data that I need to decipher, the algorithm (RC4) and the key. However, to decipher the data, one instruction I got is that "the length of the key initially gets skipped" or that "len bytes are skipped initially".
What does this mean exactly? Does it mean that if my key is 10 bytes long, that I need to pass in the binary data without the first 10 bytes to the decipher and then concatenate the first 10 bytes with the deciphered bytes?
const decipher = crypto.createDecipheriv('RC4', 'mysuperkey', null);
const buffer = decipher.update(data.slice('mysuperkey'.length));
decipher.final();
This does not work, so I might not understand the instruction.
RC4 is insecure for the first bits, so often you are instructed to skip over some initial bytes of the key stream. The way a stream cipher works is that it creates a stream of pseudo random data that depends on the key. That stream is XOR'ed with the plaintext to create the ciphertext, and with the ciphertext to create the plaintext.
To skip a number of bytes of the key stream you can simply encrypt / decrypt some (zero valued) bytes and throw away the results. This goes both for encryption and decryption. If the API has a specific skip method then you should of course use that, but I don't think it is present in CryptoJS.

How can I shorten a hexadecimal string further?

I am using MongoDB's build in id fields to label products and for ease of usage/typability, I would like to compress the _id field down from a hexadecimal string that looks like 5b69c35ac2cc78c8979a8a9b to something shorter and involving all letters of the alphabet (both uppercase and lowercase) and numbers. preferably it would involve no more than 10 or 12 characters. Are there any common methods of accomplishing this in Node.JS/MongoDB?
You could convert them to base64, that would make them 16 characters long.
Example:
Buffer.from('5b69c35ac2cc78c8979a8a9b', 'hex').toString('base64') // W2nDWsLMeMiXmoqb
It's better if you can directly access the Buffer - converting many ObjectIds from string could be costly.
The code 5b69c35ac2cc78c8979a8a9b is 24 bytes long (in hex), which means the absolute minimum number of bytes needed to represent this value without losing information is 12, ranging from 0-255 which is not what we want.
If we take a look at the ObjectId we could (maybe) eliminate some bytes:
a 4-byte value representing the seconds since the Unix epoch,
a 3-byte machine identifier,
a 2-byte process id, and
a 3-byte counter, starting with a random value.
Removing machine identifier and process id (if all id's are generated by the same process) would leave us with 7 bytes (0-255), which is still not ideal to encode in base64 or even base32.
So it would probably be better to just use a 32 bit unsigned integer for the product codes and display it as hex using 8 bytes (the leading zeros could be removed).
Encoding those 4 bytes in base64 wouldn't help much (every 3 bytes become 4 bytes), and personally I would prefer case insensitive id's for use in url's which would leave us only with base32.
For better ease of usage/typability than hexadecimal, those 4 bytes could be encoded in z-base-32 and would fit in 7 bytes without padding (7 * 5 bits = 35 bits).

Is base64 encoded file smaller than straight hexdump?

I was wondering if base64 provides any compression compared to straight hex-dump - that means turning every byte into two characters from range [a-f0-9].
Yes it does, because base64 has more characters to work with—64 instead of the 16 of hexdump. This is one of the purposes of base64.
The Wikipedia article shows you the gain: If the binary data is n bytes, the base64 data is 4*ceil(n/3) bytes. (Compared to 2*n bytes for the hexdump.)
So, instead of a 100% overhead, you get roughly a 33% overhead.

How do I pre-determine the length of the resultant cipher text produced in an encryption operation?

I have an application which stores some information in an encrypted state, both on file and in a database. How can I calculate what the length of the resultant cipher text will be based on the plain text input?
The encryption operation consists of using the .NET RijndaelManaged class/algorithm and then a conversion to a Base64 string prior to storage.
What I want to be able to do is to know beforehand how long the encrypted string will be for a given input so that I can limit the length of the input accordingly in relation to the storage space available for its encrypted form (if that makes sense!).
Thanks
Rijndael's output is the same size as the input, rounded up to the next closest multiple of the block size (usually 128 bits, aka 16 bytes). Base64 expands its input to its output by 4/3 -- it takes 4 bytes of output to represent each 3 bytes of input.
So if you have for example an input of 70 bytes, the encrypting step will produce 80 bytes of output (closest multiple of 16 that's > 70), Base64 will turn that into 108 (81/3 times 4).
The encrypted text will be the first cipher block size multiple bigger than you text. You check your Algorithm BlockSize property. Pure Base64 encoding increases the output by a third, but this can vary if you also need to URL escape (percent encode) certain Base64 symbols (like '+' and '/').

Resources