There are two different question here :
1- how do we send data and how nodes decrypt each layer of encryption?
2- how do we get data from exit node?
About first question, I can say there is no public key encryption for sending data to destination, But Shared Secrets. Before this you should know enough about D-H.
- Alice and Bob agree on a finite cyclic group G and a generating
element g in G. (This is usually done long before the rest of the
protocol; g is assumed to be known by all attackers.) We will write
the group G multiplicatively.
- Alice picks a random natural number a and sends g^a to Bob.
- Bob picks a random natural number b and sends g^b to Alice.
- Alice computes (g^b)^a.
- Bob computes (g^a)^b.
After these steps Alice and Bob have a Shared Secret s and no one knows about this Shared Secret.
Tor Steps :
- OP(onion proxy or source) sends g^a to Node1(onion router).(but encrypted by Node1's public key)
- Node1 decrypts data with private key and then sends g^b to OP.(in clear text. because if OP's public key known to ORs then where is privacy!!).
- Now OP and Node1 have a Shared Secret.[e.g: SS1 = OP & Node1 = 2].
- OP sends g^a to Node1 which Node1 should send that to Node2.('a' is a new random number)
OP encrypts g^a with Node2 Public Key, and encrypts data(en(g^a) and Node2 address) with SS1.
- Node1 decrypts data with SS1 and gets Node2 address, and sends remaining encrypted g^a to Node2.
- Node2 decrypts data with her private key, and then sends g^b to Node1 again.(clear text)
- Node1 encrypts g^b with SS1 and sends to OP.
- OP decrypts data with SS1.
- Now OP and Node2 have a Shared Secret which Node1 doesn't know.[e.g: SS2 = OP & Node2 = 5].
This will be continued until the circuit complete.now OP can send request for destination through Nodes with (SS1, SS2 , ...). last sending request should be like this :
OP to Node1 => encryptSS1(send to Node2, encryptSS2(send to destination, "hello server"))
And about second question receiving response should be like this :
- Dest to Node2 => "hello client"
- Node2 to Node1 => encryptSS2("hello client")
- Node1 to OP => encryptSS1(encryptSS2("hello client"))
- OP decryptSS1(decryptSS2(data)).
Take a look at an image on this page :
Onion routing - pikneek