গল্ফিং শেষ থেকে শেষের এনক্রিপশন


16

এই চ্যালেঞ্জটি প্রথমে উত্তর দেওয়ার জন্য 200 পয়েন্টের সওয়াব বহন করে এবং কমপক্ষে 3 দিনের জন্য অপরাজিত থাকে। ব্যবহারকারী দ্বারা দাবি করা হয়েছে 3080953

এন্ড-টু-এন্ড এনক্রিপশন সম্পর্কে ইদানীং অনেক কথা হয়েছে এবং সংস্থাগুলি তাদের পণ্যগুলি থেকে এটি সরিয়ে নেওয়ার জন্য চাপ দেয়। আমি এর অধিকার-ভুল সম্পর্কে আগ্রহী নই, তবে আমি ভাবলাম: কোডটি কীভাবে সংক্ষিপ্ত হতে পারে যে কোনও সংস্থাকে এটি ব্যবহার না করার জন্য চাপ দেওয়া হবে?

এখানে চ্যালেঞ্জটি হ'ল দুটি নেটওয়াক সিস্টেমের মধ্যে একটি ডিফি হেলম্যান কী এক্সচেঞ্জ বাস্তবায়ন করা , তারপরে ব্যবহারকারীদের উত্পন্ন প্রতিসাম্য কীটি ব্যবহার করে পিছনে এবং বাইরে যোগাযোগ করার অনুমতি দেওয়া। এই কাজের উদ্দেশ্যে, অন্য কোনও সুরক্ষার প্রয়োজন নেই (যেমন কীটি চালানো, পরিচয় যাচাই করা, ডস এর বিরুদ্ধে সুরক্ষা দেওয়ার দরকার নেই) এবং আপনি একটি উন্মুক্ত ইন্টারনেট ধরে নিতে পারেন (আপনি যে কোনও বন্দর শুনেছেন তা সবার জন্য উপলব্ধ)। বিল্টিনগুলির ব্যবহার অনুমোদিত এবং উত্সাহিত!

আপনি দুটি মডেলের একটি বেছে নিতে পারেন:

  • একটি সার্ভার এবং একটি ক্লায়েন্ট: ক্লায়েন্ট সার্ভারের সাথে সংযুক্ত হয়, তারপরে সার্ভার বা ক্লায়েন্ট অন্যকে বার্তা পাঠাতে পারে। দুজনের মধ্যে থাকা তৃতীয় পক্ষগুলি অবশ্যই বার্তাগুলি পড়তে অক্ষম হবে। একটি উদাহরণ প্রবাহ হতে পারে:
    1. ব্যবহারকারী এ সার্ভার চালু করে
    2. ব্যবহারকারী বি ক্লায়েন্ট প্রবর্তন করে এবং এটি এ এর ​​সার্ভারের দিকে নির্দেশ করে (যেমন আইপি / পোর্টের মাধ্যমে), প্রোগ্রামটি একটি সংযোগ খোলে
    3. ব্যবহারকারী এ এর ​​প্রোগ্রামটি সংযোগটিকে স্বীকৃতি দেয় (allyচ্ছিকভাবে প্রথমে ব্যবহারকারীকে সম্মতির জন্য জিজ্ঞাসা করে)
    4. ব্যবহারকারীর বি এর প্রোগ্রামটি ডিএইচ গোপন তৈরি করা শুরু করে এবং প্রয়োজনীয় তথ্য (পাবলিক কী, প্রাইম, জেনারেটর, আপনার প্রয়োগের জন্য প্রয়োজনীয় যে কোনও কিছু) ব্যবহারকারী এগুলিতে প্রেরণ করে
    5. ব্যবহারকারীর এ প্রোগ্রামটি ভাগ করা গোপনীয়তা তৈরির জন্য প্রেরিত ডেটা ব্যবহার করে এবং প্রয়োজনীয় তথ্য (পাবলিক কী) ব্যবহারকারী বিতে ফেরত পাঠায় এদিক থেকে ব্যবহারকারী এ বার্তা প্রবেশ করতে পারে (যেমন স্টিডিনের মাধ্যমে) যা এনক্রিপ্ট করা হবে এবং ব্যবহারকারীর কাছে প্রেরণ করা হবে বি (যেমন স্টাডাউট)
    6. ব্যবহারকারীর বি এর প্রোগ্রাম ভাগ করা গোপনীয়তা তৈরি করে। এই বিন্দু থেকে, ব্যবহারকারী বি ব্যবহারকারী এতে বার্তা প্রেরণ করতে পারে
  • বা: এটির সাথে সংযুক্ত দুটি ক্লায়েন্ট সহ একটি সার্ভার: প্রতিটি ক্লায়েন্ট সার্ভারের সাথে কথা বলে, যা তাদের বার্তাটি অন্য ক্লায়েন্টের কাছে ফরোয়ার্ড করে। সার্ভার নিজেই (এবং এর মধ্যে থাকা কোনও তৃতীয় পক্ষ) অবশ্যই বার্তাগুলি পড়তে অক্ষম হবে। প্রাথমিক সংযোগ ব্যতীত, প্রক্রিয়াটি প্রথম বিকল্পটিতে বর্ণিত হিসাবে একই।

বিস্তারিত নিয়ম:

  • আপনি একটি একক প্রোগ্রাম, বা একাধিক প্রোগ্রাম (যেমন সার্ভার এবং ক্লায়েন্ট) সরবরাহ করতে পারেন। আপনার স্কোর সমস্ত প্রোগ্রাম জুড়ে মোট কোড আকার।
  • আপনার প্রোগ্রামটি অবশ্যই তাত্ত্বিকভাবে কোনও নেটওয়ার্কের সাথে যোগাযোগের জন্য সক্ষম হতে হবে (তবে পরীক্ষার জন্য, লোকালহোস্ট ভাল আছে)। আপনার পছন্দের ভাষা যদি নেটওয়ার্কিং সমর্থন করে না, আপনি এটিকে এমন কোনও কিছুর সাথে একত্রিত করতে পারেন (যেমন শেল স্ক্রিপ্ট); এক্ষেত্রে আপনার স্কোরটি ব্যবহৃত সমস্ত ভাষায় মোট কোড আকার।
  • ডিফি হেলম্যান কী প্রজন্ম হার্ড-কোডড "পি" এবং "জি" মান ব্যবহার করতে পারে।
  • উত্পন্ন শেয়ার্ড কীটি কমপক্ষে 1024 বিট হতে হবে।
  • কীটি ভাগ হয়ে গেলে, প্রতিসম কী-এনক্রিপশন পছন্দ আপনার উপর নির্ভর করে, তবে আপনাকে অবশ্যই এমন কোনও পদ্ধতি বাছাই করতে হবে না যা বর্তমানে এটির বিরুদ্ধে ব্যবহারিক আক্রমণ রয়েছে (যেমন সিজার শিফটটি কীটির অজান্তেই বিপরীত দিকে তুচ্ছ হয়) )। অনুমোদিত অ্যালগরিদম উদাহরণ:
    • এইএস (কোনও মূল আকার)
    • আরসি 4 (তাত্ত্বিকভাবে ভাঙ্গা, তবে এমন কোনও ব্যবহারিক আক্রমণ যা আমি উল্লেখ করতে পারি না, তাই এটি এখানে অনুমোদিত)
  • ব্যবহারকারী এ এবং বি উভয়কে অবশ্যই একে অপরকে (দ্বি-মুখী যোগাযোগ) ইন্টারেক্টিভ বার্তাগুলি প্রেরণ করতে সক্ষম হতে হবে (যেমন স্টিডিনের লাইনগুলি পড়া, ক্রমাগত প্রম্পট করা বা কোনও বোতাম টিপানোর মতো ইভেন্ট)। যদি এটি আরও সহজ করে তোলে, আপনি একটি বিকল্প কথোপকথন ধরে নিতে পারেন (যেমন কোনও ব্যবহারকারী কোনও বার্তা প্রেরণের পরে তাদের পরবর্তী বার্তা প্রেরণের আগে তাদের অবশ্যই প্রতিক্রিয়ার জন্য অপেক্ষা করতে হবে)
  • ভাষা builtins হয় অনুমতি (যদি ইতিমধ্যে তারা সমর্থিত করছি আপনার নিজের ক্রিপ্টোগ্রাফিক বা নেটওয়ার্কিং পদ্ধতি লিখতে কোন প্রয়োজন)।
  • অন্তর্নিহিত যোগাযোগ বিন্যাসটি আপনার উপর নির্ভর করে।
  • উপরে বর্ণিত যোগাযোগের পদক্ষেপগুলি উদাহরণ, তবে আপনাকে সেগুলি অনুসরণ করার প্রয়োজন নেই (যতক্ষণ না প্রয়োজনীয় তথ্য ভাগ করা হয়, এবং কোনও মধ্যবিত্ত পুরুষ ভাগ করা কী বা বার্তা গণনা করতে সক্ষম হয় না)
  • আপনার সার্ভারের সাথে সংযোগের জন্য প্রয়োজনীয় বিশদগুলি যদি আগে থেকে জানা না যায় (যেমন এটি কোনও এলোমেলো বন্দরে শোনা যায়), এই বিবরণগুলি অবশ্যই মুদ্রিত করা উচিত। আপনি ধরে নিতে পারেন যে মেশিনের আইপি ঠিকানাটি জানা গেছে।
  • ত্রুটি পরিচালনার ক্ষেত্রে (যেমন অবৈধ ঠিকানা, হারিয়ে যাওয়া সংযোগ ইত্যাদি) প্রয়োজনীয় নয়।
  • চ্যালেঞ্জটি কোড গল্ফ, তাই বাইটের মধ্যে সংক্ষিপ্ততম কোডটি জয়ী।

হার্ডকোডিং pএবং gঅনুমোদিত?
ASCII- কেবল

@ এএসসিআইআই-কেবল আমি যা বলতে পারি তার থেকে, হার্ড-কোডিং ভাল মানের পি & জি মানগুলি সূক্ষ্ম হিসাবে বিবেচনা করা হয় (যদি না বিকাশকারী ক্ষতিকারকভাবে নির্দিষ্ট আক্রমণগুলির জন্য ঝুঁকিপূর্ণ বলে পরিচিত মানগুলি ব্যবহার না করে)। সুতরাং এই চ্যালেঞ্জের জন্য এটি ঠিক আছে (যতক্ষণ না ফলাফলটি গোপনে কমপক্ষে 1024 বিট হয়)
ডেভ

উত্তর:


3

নোড.জেএস ( 372 423 + 94 = 517 513 বাইট)

Golfed

"পাঠযোগ্যতা" এর জন্য লাইন ব্রেকগুলি যুক্ত করা হয়েছে।

chat.js ( 423 419 বাইট)

কোন লাইন বিরতি

[n,c,p]=["net","crypto","process"].map(require);r="rc4",a="create",h="DiffieHellman",z="pipe",w="write",o=128,g=p.argv;s=e=d=0,y=c[a+h](8*o),k=y.generateKeys();v=n.connect(9,g[2],_=>{g[3]&&(v[w](y.getPrime()),v[w](k));v.on("data",b=>{s||(g[3]||(y=c[a+h](b.slice(0,o)),k=y.generateKeys(),v[w](k),b=b.slice(o)),s=y.computeSecret(b),e=c[a+"Cipher"](r,s),p.stdin[z](e)[z](v),d=c[a+"Decipher"](r,s),v[z](d)[z](p.stdout))})})

লাইন ব্রেক

[n,c,p]=["net","crypto","process"].map(require);
r="rc4",a="create",h="DiffieHellman",z="pipe",w="write",o=128,g=p.argv;
s=e=d=0,y=c[a+h](8*o),k=y.generateKeys();
v=n.connect(9,g[2],_=>{g[3]&&(v[w](y.getPrime()),v[w](k));
v.on("data",b=>{s||(g[3]||(y=c[a+h](b.slice(0,o)),k=y.generateKeys(),
v[w](k),b=b.slice(o)),s=y.computeSecret(b),e=c[a+"Cipher"](r,s),p.stdin[z](e)[z](v)
,d=c[a+"Decipher"](r,s),v[z](d)[z](p.stdout))})})

প্রতিধ্বনি_সারবার.জে (94 বাইট)

c=[],require("net").createServer(a=>{c.forEach(b=>{a.pipe(b),b.pipe(a)});c.push(a)}).listen(9);

Ungolfed

নোডের অন্তর্নির্মিত নেটওয়ার্কিং এবং ক্রিপ্টো ক্ষমতা রয়েছে। এটি নেটওয়ার্কিংয়ের জন্য টিসিপি ব্যবহার করে (কারণ এটি এইচটিটিপি-র জন্য নোডের ইন্টারফেসের চেয়ে সহজ, এবং এটি স্ট্রিমগুলির সাথে দুর্দান্ত অভিনয় করে)।

আমি ব্লক আকারের সাথে ডিল করতে এড়াতে AES এর পরিবর্তে একটি স্ট্রিম সাইফার (আরসি 4) ব্যবহার করি। উইকিপিডিয়া মনে করে এটি এটি ঝুঁকিপূর্ণ হতে পারে, সুতরাং যদি কারও কাছে অন্তর্দৃষ্টি থাকে তবে সাইফারদের মধ্যে অগ্রাধিকার দেওয়া হয়, তা দুর্দান্ত।

ইকো সার্ভারটি চালান node echo_server.jsযা পোর্ট 9 এ শুনবে এবং এই প্রোগ্রামটির দুটি দৃষ্টান্ত দিয়ে চালান node chat.js <server IP>এবং node chat.js <server IP> 1(শেষ যুক্তিটি সেট করে যা একটি প্রাইম প্রেরণ করে)। প্রতিটি উদাহরণ ইকো সার্ভারের সাথে সংযোগ স্থাপন করে। প্রথম বার্তা কী প্রজন্মকে পরিচালনা করে এবং পরবর্তী বার্তাগুলি স্ট্রিম সাইফারটি ব্যবহার করে।

ইকো সার্ভার কেবলমাত্র সংযুক্ত সমস্ত ক্লায়েন্টকে আসল ব্যতীত সমস্ত কিছু পাঠায়।

মক্কেল

var net = require('net');
var crypto = require('crypto');
var process = require('process');
let [serverIP, first] = process.argv.slice(2);

var keys = crypto.createDiffieHellman(1024); // DH key exchange
var prime = keys.getPrime();
var k = keys.generateKeys();
var secret;

var cipher; // symmetric cipher
var decipher;

// broadcast prime
server = net.connect(9, serverIP, () => {
    console.log('connect')
    if(first) {
        server.write(prime);
        console.log('prime length', prime.length)
        server.write(k);
    }

    server.on('data', x => {
        if(!secret) { // if we still need to get the ciphers
            if(!first) { // generate a key with the received prime
                keys = crypto.createDiffieHellman(x.slice(0,128)); // separate prime and key
                k = keys.generateKeys();
                server.write(k);
                x = x.slice(128)
            }

            // generate the secret
            console.log('length x', x.length);
            secret = keys.computeSecret(x);
            console.log('secret', secret, secret.length) // verify that secret key is the same
            cipher = crypto.createCipher('rc4', secret);
            process.stdin.pipe(cipher).pipe(server);
            decipher = crypto.createDecipher('rc4', secret);
            server.pipe(decipher).pipe(process.stdout);
        }
        else {
            console.log('sent text ', x.toString()) // verify that text is sent encrypted
        }
    });
})

ইকো সার্ভার

var net = require('net');
clients = [];

net.createServer(socket => {
    clients.forEach(c=>{socket.pipe(c); c.pipe(socket)});
    clients.push(socket);
}).listen(9)

সমস্ত টিপস + প্রতিক্রিয়া জন্য ধন্যবাদ ডেভ!


1
গল্ফযুক্ত সংস্করণে পঠনযোগ্যতা যুক্ত করবেন না, এটি অদৃশ্য সংস্করণ। বা যদি আপনি এটি করেন তবে রেখাটি ভাঙ্গার আগে সেমিকোলনগুলি সরিয়ে ফেলুন, সুতরাং এটি একই দৈর্ঘ্য।
mbomb007

@ mbomb007 "পঠনযোগ্যতা" বেশিরভাগই স্ক্রোল হওয়া এড়ানোর জন্য। দুর্ভাগ্যক্রমে, কোডের মূল অংশের কোনও অর্ধসীমা নেই, যাতে এটি কাজ করে না। আমি দ্রুত অনুসন্ধান করেছি এবং প্রতিস্থাপনটি খুব বেশি কঠোর হবে না। ভবিষ্যতের মন্তব্যের জন্য অবশ্যই আপনার পরামর্শটি মনে রাখবেন!
ব্যবহারকারী 3080953

@ সমস্ত প্রতিক্রিয়া জন্য ডেভ ধন্যবাদ! আমি ভ্যানিলা ডিএইচ ব্যবহার করতে পরিবর্তন করেছি, যা আসলে বেশ কয়েকটি দৈর্ঘ্যের যোগ করেছে কারণ আপনাকে প্রাইম এক্সচেঞ্জ করতে হবে পাশাপাশি এএস আসলে ড্রপ-ইন প্রতিস্থাপন হিসাবে কাজ করে, তবে এইএসের সমস্যাটি হ'ল আপনি সম্পূর্ণ না হওয়া পর্যন্ত কিছুই প্রেরণ করে না একটি ব্লক, এবং প্যাডিং একটি ব্যথা হবে। এছাড়াও rc4 aes128 এর চেয়ে সংক্ষিপ্ত
ব্যবহারকারী 3080953

1
এটি কোনও নেটওয়ার্কের মাধ্যমে কাজ করবে কিনা তা সম্পর্কে আমি নিশ্চিত ছিলাম না তবে সম্ভবত এটি হবে না এবং আমি এটি একটি বাসে লিখেছিলাম যাতে আমার চেক করার কোনও উপায় ছিল না। নতুন সংস্করণ পরিবর্তে ইকো সার্ভার ব্যবহার করে। এটি সময়সীমা সমস্যাও সমাধান করে। আমি একটি সার্ভার + ক্লায়েন্ট এড়ানোর চেষ্টা করছিলাম তবে এটি আরও ভাল ফর্ম। অবশেষে, এই চ্যালেঞ্জের জন্য ধন্যবাদ, আমি যেখান থেকে কেবল লাইব্রেরি দখল করার পরিবর্তে নোডটি কীভাবে ব্যবহার করতে পারি তার সম্পর্কে আমি এক টন শিখেছি :)
ব্যবহারকারীর 3080953

@ ব্যবহারকারী 3080953 ভাল শোনাচ্ছে। এই আপডেটগুলির সাথে আপনার অনুগ্রহের জন্য দৌড়াতে হবে!
ডেভ

0

নোড.জেএস, 638 607 বাইট

এখন এটি ভাল এবং সত্যই মারধর করা হয়েছে (এবং একই ভাষায়), এখানে আমার পরীক্ষার উত্তরটি দেওয়া হল:

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])

ব্যবহার

এটি একটি সার্ভার / ক্লায়েন্ট বাস্তবায়ন; একটি ইনস্ট্যান্টেশন হ'ল সার্ভার এবং অন্যটি ক্লায়েন্ট। সার্ভারটি একটি নির্দিষ্ট বন্দর দিয়ে চালু করা হয়, তারপরে ক্লায়েন্টটিকে সার্ভারের বন্দরের দিকে নির্দেশ করা হয়। আপনার মেশিনটি এনট্রপিতে কম থাকলে ডিএইচ সেট আপ করতে কয়েক সেকেন্ড সময় নিতে পারে, তাই প্রথম বার্তাগুলি কিছুটা বিলম্বিত হতে পারে।

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)।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.