I'm trying to create a very simple & lightweight client implementation of the SSH protocol for node.js.
The following documentation confuses me totally:
http://www.snailbook.com/docs/transport.txt
It lacks a full example of the whole key exchange thing. There are many things well explained, but I'm not really sure how to put those things together.
Could you help me to put an example together?
I'm stuck after section 7.1. I successfully receive the list of alorightms of the server, and I send a list with only the required alorithms to the server. Also successful.
So, in this case we have the following alorightms:
kex: diffie-hellman-group1-sha1
key: ssh-dss
encryption: 3des-cbc
mac: hmac-sha1
After that, I skipped section 7.2 and 7.3 and continued directly to section 8, since generating a key needs the values H & K, which are generated in section 8.
But section 8 does not make sense to me. It requires both the client & the server to already know the same prime, generator and order value. When have those values been negotiated an sent to each other? Section 8 cleary says that it directly follows the algorithm exchange, so there is nothing between those steps...
Am I missing something?
Thanks really much for your help!
The prime is specified by the key-exchange algorithm. For example, to quote from your source:
The "diffie-hellman-group1-sha1" method specifies the Diffie-Hellman key exchange with SHA-1 as HASH, and Oakley Group 2 [RFC2409] (1024-bit MODP Group).
And if you consult RFC 2409 ยง6.2, you'll find:
The prime is 2^1024 - 2^960 - 1 + 2^64 * { [2^894 pi] + 129093 }. Its hexadecimal value is FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1
29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD
EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245
E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED
EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE65381
FFFFFFFF FFFFFFFF The generator is 2 (decimal)
Related
Beginner here trying to understand on a low-level how websockets work. I am trying to create my own implementation, however I am very confused on the logic of parsing the data frame that get's sent from client => server.
I know the buffer that is received on the server side consists of multiple bytes, with the first two being the main header information (fin bit, length, opcode, mask, etc).
I found the following code on SO that parses both the bytes, and from testing, it DOES indeed return the correct values.
let index = 0;
frame = {
data: new Buffer(0),
fin: (buffer[index] & 128) === 128,
length: buffer[index + 1] & 127,
masked: (buffer[index + 1] & 128) === 128,
opcode: buffer[index] & 15
}
What my main question is though.... HOW exactly is this returning the correct values?
I know buffer[index] and buffer[index+1] are referring to the first and second byte, and the AND operand is being used to compare the binary values of each, and output 1 whenever both indexes in both numbers equal to 1, otherwise 0...... but...
Where do the numbers after the & operator come from? ex: opcode is 15, length is 127.
HOW exactly does using the AND operator on both these values, give the right result? This is what I really don't understand.
I apologize if this is basic computer science concepts that I'm not understanding, but if anyone out there is able to explain to me what exactly is occurring with this code, it would be so much appreciated.
I get that it looks like a normal AND comparison but rather it is a boolean AND comparison being made.
To clarify a bit more specific, buffer[index] & 15 for opcode says compare buffer[index] as a binary number with 15(this is the highest allowed opcode for websockets) as a binary number bit by bit and return the binary results as an integer, the opcode itself tells which frame type is being sent.(If you are curious you can deep dive on this here https://www.rfc-editor.org/rfc/rfc6455#section-11.8.)
On the length part of 127 I refer to this answer on SO since it is a solid answer: how to work out payload size from html5 websocket
For further reading on the operator see the section in my source on bitwise logical operators.
Source: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators
StackOverflow warns me that I may be down-voted for this question, but I'd appreciate your not doing so, as I post this simply to try to understand a programming exercise I've been posed with, and over which I've been puzzling a while now.
I'm doing some javascript coding exercises and one of the assignments was to devise an "encryption function", encipher, which would encrypt a 4-digit number by multiplying it by a number sufficiently low such that none of its digits exceeds 9, so that a 4-digit number is returned. Thus
encipher(0204)
might yield
0408
where the multiplier would have been 2. -- This is very basic material, simply to practice the Javascript. -- But as far as I can see, the numbers returned can never be deciphered (which is the next part of the exercise). Even if you store a dictionary internal to encipher, along the lines of
{'0408':'2'}, etc
so that you could do a lookup on 0408 and return 0204, these entries could not be assured to be unique. If one for example were to get the number 9999 to be deciphered, one would never know whether the original number was 9999 (multiplied by 1), 3333 (multiplied by 3) or 1111 (multiplied by 9). Is that correct? I realise this is a fairly silly and artificial problem, but I'm trying to understand if the instructions to the exercise are not quite right, or if I'm missing something. Here is the original problem:
Now, let's add one more level of security. After changing the position of the digits, we will multiply each member by a number whose multiplication does not exceed 10. (If it is higher than 10, we will get a two-digit multiplication and the code will no longer be 4 values). Now, implement in another function the decrypter (), which will receive as an argument an encrypted code (and correspondingly multiplied in the section above and return the decrypted code.
Leaving the exercise behind, I'm just curious whether there exists any way to "encrypt" (when I say "encrypt", I mean at a moderate javascript level, as I'm not a cryptography expert) an n-digit number and return a unique n-digit number?
Thanks for any insights. --
encrypt a 4-digit number by multiplying it by a number sufficiently low such that none of its digits exceeds 9, so that a 4-digit number is returned
If your input is 9999, there is no integer other than 1 or 0 that you can multiply your input by and get a positive number with a maximum of 4 digits. Therefore, there is no solution that involves only integer multiplication. However, integer multiplication can be used as part of an algorithm such as rotating digits (see below).
If instead you're looking for some sort of bijective algorithm (one that uniquely maps A to B and B to A), you can look at something like rotating the digits left or right, reversing the order of the digits, or using a unique mapping of each individual digit to another. Those can also be mixed.
Examples
Rotate
1234 -> 2341
Reverse
1234 -> 4321
Remap digits e.g. 2 mapped to 8, 3 mapped to 1
2323 -> 8181
Note that none of these are cryptographically sound methods to encrypt information, but they do seem to more-or-less meet the objectives of the exercise.
Hello dear swarm intelligence,
One of my current private projects is in the field of the internet of things, specifically LoRaWan and TTN. For easy data-handling I decided to use node-red which is a node-js based flow tool to process the received data.
This is the first time ever I have encoutered contact with the javascript world (apart from minor reading ;)). Here's the problem:
I am transmitting an C-Style int16_t signed type devided into two 8-bit nibbles via ttn. On the receiving site I want to merge these two nibbles again into a signed 16 bit type. Well the problem is that javascript only supports 32-bit intergers which means by simply mergin them via bitwise operations like this:
newMsg.payload=(msg.payload[1]<<8)|(msg.payload[0]);
I lose the signed information and just get the unsigned interpretation of the data, since it is not stored in a 32-bit two's complement.
Since I am not yet firmly familiar with the javascript "standard library" this seems like a hard problem for me!
Any help will be appreciated
var unsignedValue = (msg.payload[1] << 8) | (msg.payload[0]);
if (result & 0x8000) {
// If the sign bit is set, then set the two first bytes in the result to 0xff.
newMsg.payload = unsignedValue | 0xffff0000;
} else {
// If the sign bit is not set, then the result is the same as the unsigned value.
newMsg.payload = unsignedValue;
}
Note that this still stores the value as a signed 32-bit integer, but with the right value.
I'm trying to set up a gpg key generator/manager web based using openpgpjs and an openpgp server.
I'm able to generate the key pair with no trouble at all, but when I want to send the armored public key to the pks, I get an error: "Error decoding keyblock".
After several tries (with url encoding, with no url encoding, through Ajax request or with a copy/paste directly on the pks' form...), I decided to try and import it in GnuPG : it worked!
Then I tried to export the key from GnuPG and copy the result in the pks's form, it worked too.
So I tried to compare the imported file and the exported one expecting that some CR+LF would be differents. I was surprised that the entire ASCII-armored key is different.
So I have two questions:
how is it possible for the same key to have two different ASCII-armor?
how can I have my Javascript issue an armored key that will be accepted by the pks?
As stated by #owlstead, the two applications are using different version of the open PGP protocol. Openpgpjs provides ASCII armored key using the new format while pks only accept the old format.
You need to decode the first byte of the key to notice it:
Take the first 2 letters of the key and use the radix-64 table to get the binary value, then check the first 8 bits (one byte).
The first bit is always one, the second one should be one too (it means it's a new packet), then the following is the binary value corresponding to the content of the ASCII armor :
0 -- Reserved - a packet tag must not have this value
1 -- Public-Key Encrypted Session Key Packet
2 -- Signature Packet
3 -- Symmetric-Key Encrypted Session Key Packet
4 -- One-Pass Signature Packet
5 -- Secret Key Packet
6 -- Public Key Packet
7 -- Secret Subkey Packet
8 -- Compressed Data Packet
9 -- Symmetrically Encrypted Data Packet
10 -- Marker Packet
11 -- Literal Data Packet
12 -- Trust Packet
13 -- User ID Packet
14 -- Public Subkey Packet
In the old format, the binary value is coded on 4 bits (bits 5 to 2), in the new one, it's on 6 bits (from 5 to 0).
More details can be found in RFC 2440, chapter 4.
Some of the PGP packets could be exchanged, e.g., if you have more than one non-primary UIDs, or more than one subkeys. Next, there is a new packet format, that causes a different ASCII armor too. And last but not least the signature packets contain the left two bytes of the hash value, which are no more checked. If you change them, you will hardly detect the change when looking at it, but the CRC24 sum at the end will change.
I have the following JSON:
[{"hashcode": 4830991188237466859},{...}]
I have the following Angular/JS code:
var res = $resource('<something>');
...
res.query({}, function(json) {hashcode = json[0].hashcode;};
...
Surprisingly (to me, I'm no JS expert), I find that something (?) is rounding the value to the precision of 1000 (rounding the last 3 digits). This is a problem, since this is a hash code of something.
If, on the other hand I write the value as a String to the JSON, e.g -
[{"hashcode": "4830991188237466859"},{...}]
this does not happen. But this causes a different problem for me (with JMeter/JSON Path, which extracts the value ["4830991188237466859"] by running my query $.hashcode - which I can't use as a HTTP request parameter (I need to add ?hashcode=... to the query, but I end up with ?hashcode=["..."]
So I appreciate help with:
Understanding who and why -- is rounding my hash, and how to avoid it
Help with JMeter/JSON Path
Thanks!
Each system architecture has a maximum number it can represent. See Number.MAX_VALUE or paste your number into the console. You'll see it happens at the JavaScript level, nothing to do with angular. Since the hash doesn't represent the amount of something, it's perfectly natural for it to be a string. Which leads me to
Nothing wrong with site.com/page?hashcode=4830991188237466859 - it's treated as a string there and you should keep treating it as such.
The javascript Number type is floating point based, and can only represent all integers in the range between -253 and 253. Some integers outside this range are therefore subject to "rounding" as you experience.
In regards to JMeter JSON Path Extractor plugin, the correct JSON Path query for your hashcode will look like
$..hashcode[0]
See Parsing JSON chapter of the guide for XPath to JSON Path mappings and more details.