Node.js,638字节
既然它已经被击败了(并且用相同的语言),这是我的测试答案:
R=require,P=process,s=R('net'),y=R('crypto'),w=0,C='create',W='write',D='data',B='hex',G=_=>a.generateKeys(B),Y=(t,m,g,f)=>g((c=y[C+t+'ipher']('aes192',w,k='')).on('readable',_=>k+=(c.read()||'').toString(m)).on('end',_=>f(k)))+c.end(),F=C+'DiffieHellman',X=s=>s.on(D,x=>(x+'').split(B).map(p=>p&&(w?Y('Dec','utf8',c=>c[W](p,B),console.log):P.stdin.on(D,m=>Y('C',B,c=>c[W](m),r=>s[W](r+B)),([p,q,r]=p.split(D),r&&s[W](G(a=y[F](q,B,r,B))),w=a.computeSecret(p,B))))));(R=P.argv)[3]?X(s.Socket()).connect(R[3],R[2]):s[C+'Server'](s=>X(s,a=y[F](2<<9))[W](G()+D+a.getPrime(B)+D+a.getGenerator(B)+B)).listen(R[2])
或包装:
R=require,P=process,s=R('net'),y=R('crypto'),w=0,C='create',W='write',D='data',B
='hex',G=_=>a.generateKeys(B),Y=(t,m,g,f)=>g((c=y[C+t+'ipher']('aes192',w,k=''))
.on('readable',_=>k+=(c.read()||'').toString(m)).on('end',_=>f(k)))+c.end(),F=C+
'DiffieHellman',X=s=>s.on(D,x=>(x+'').split(B).map(p=>p&&(w?Y('Dec','utf8',c=>c[
W](p,B),console.log):P.stdin.on(D,m=>Y('C',B,c=>c[W](m),r=>s[W](r+B)),([p,q,r]=p
.split(D),r&&s[W](G(a=y[F](q,B,r,B))),w=a.computeSecret(p,B))))));(R=P.argv)[3]?
X(s.Socket()).connect(R[3],R[2]):s[C+'Server'](s=>X(s,a=y[F](2<<9))[W](G()+D+a.
getPrime(B)+D+a.getGenerator(B)+B)).listen(R[2])
用法
这是服务器/客户端实现;一个实例将是服务器,另一个是客户端。使用特定的端口启动服务器,然后将客户端指向服务器的端口。如果您的机器熵不足,DH可能需要花费几秒钟来进行设置,因此第一条消息可能会延迟一些时间。
MACHINE 1 MACHINE 2
$ node e2e.js <port> :
: $ node e2e.js <address> <port>
$ hello :
: : hello
: $ hi
: hi :
分解
s=require('net'),
y=require('crypto'),
w=0, // Shared secret starts unknown
Y=(t,m,g,f)=>g( // Helper for encryption & decryption
(c=y['create'+t+'ipher']('aes192',w,k=''))
.on('readable',_=>k+=(c.read()||'').toString(m))
.on('end',_=>f(k)))+c.end();
X=s=>s.on('data',x=>(x+'').split('TOKEN2').map(p=>
p&&(w // Have we completed handshake?
?Y('Dec','utf8',c=>c.write(p,'hex'),console.log) // Decrypt + print messages
: // Haven't completed handshake:
process.stdin.on('data',m=> // Prepare to encrypt + send input
Y('C','hex',c=>c.write(m),r=>s.write(r+'TOKEN2')),(
[p,q,r]=p.split('TOKEN1'), // Split up DH data sent to us
r&& // Given DH details? (client)
s.write(
(a=y.createDiffieHellman( // Compute key pair...
q,'hex',r,'hex') // ...using the received params
).generateKeys('hex')), // And send the public key
w=a.computeSecret(p,'hex') // Compute shared secret
//,console.log(w.toString('hex')) // Print if you want to verify no MITM
))))),
(R=process.argv)[3] // Are we running as a client?
?X(s.Socket()).connect(R[3],R[2]) // Connect & start chat
:s.createServer(s=> // Start server. On connection:
X(s, // Start chat,
a=y.createDiffieHellman(1024)) // Calc DiffieHellman,
.write( // Send public key & public DH details
a.generateKeys('hex')+'TOKEN1'+
a.getPrime('hex')+'TOKEN1'+
a.getGenerator('hex')+'TOKEN2')
).listen(R[2]) // Listen on requested port
标记的唯一要求是它们至少包含一个非十六进制字符,因此在缩略代码中使用了其他字符串常量(data
和hex
)。
p
并g
允许?