การเข้ารหัส CipherSaber


11

ใช้โปรแกรมเข้ารหัสCipherSaberดังที่อธิบายไว้ด้านล่าง แนวทาง:

  • รายการที่เล็กที่สุดเป็นไบต์ชนะ
    • อย่างไรก็ตามในการออกจากบรรทัดฐานคุณสามารถโพสต์รายการที่น่าสนใจแม้ว่าพวกเขาจะไม่ได้รายการกอล์ฟที่ร้ายแรง
  • โดยทั่วไปแล้วรายการจะเป็นโปรแกรมที่ใช้ข้อความธรรมดาจากอินพุตมาตรฐานและเขียน ciphertext ไปยังเอาต์พุตมาตรฐานโดยมีคีย์ที่ระบุ (โดยผู้ใช้) ในบางวิธีที่คุณต้องการ
    • อย่างไรก็ตามหากคุณต้องการใช้ขั้นตอนนี้เป็นขั้นตอนก็ถือว่าใช้ได้เช่นกัน
  • IV จะต้องมาจากเครื่องกำเนิดหมายเลขเทียมแบบเข้ารหัสที่มีความปลอดภัย หากภาษาของคุณไม่รองรับให้เลือกภาษาอื่น ;-)
  • กรุณาอย่าใช้ไลบรารีที่เฉพาะเจาะจงเข้ารหัสลับการเรียกระบบหรือคำแนะนำใด ๆ (นอกเหนือจาก PRNG ตามที่ระบุไว้ข้างต้น) แน่นอนว่าการใช้งานระดับบิตเรตระดับต่ำทั่วไปนั้นโอเค

CipherSaber เป็นตัวแปรของ RC4 / Arcfour ดังนั้นฉันจะเริ่มต้นด้วยการอธิบายหลังจากนั้นการเปลี่ยนแปลง CipherSaber จะเป็นเช่นนั้น

0. RC4 / Arcfour

Arcfour มีการระบุอย่างสมบูรณ์ที่อื่นแต่เพื่อความสมบูรณ์ฉันจะอธิบายที่นี่ (ในกรณีที่มีความแตกต่างระหว่างร่างอินเทอร์เน็ตและคำอธิบายนี้อดีตเป็นบรรทัดฐาน)

การตั้งค่าคีย์

ตั้งค่าสองอาร์เรย์SและS2ทั้งความยาว 256 โดยที่k_1เป็นไบต์แรกของคีย์และk_nเป็นตัวสุดท้าย

S = [0, ..., 255]
S2 = [k_1, ..., k_n, k_1, ...]

( S2เต็มไปด้วยไบต์ของคีย์ซ้ำแล้วซ้ำอีกจนกว่า 256 ไบต์ทั้งหมดจะเต็มไป)

จากนั้นเริ่มต้นjเป็น 0 และสับเปลี่ยน 256 ครั้ง:

j = 0
for i in (0 .. 255)
    j = (j + S[i] + S2[i]) mod 256
    swap S[i], S[j]
end

การตั้งค่าคีย์เสร็จสมบูรณ์ S2อาร์เรย์จะไม่ใช้ที่นี่และสามารถนำมาขัด

การสร้างสตรีมเข้ารหัส

กำหนดค่าเริ่มต้นiและjเป็น 0 จากนั้นสร้างกระแสหลักดังต่อไปนี้:

i = 0
j = 0
while true
    i = (i + 1) mod 256
    j = (j + S[i]) mod 256
    swap S[i], S[j]
    k = (S[i] + S[j]) mod 256
    yield S[k]
end

การเข้ารหัส / ถอดรหัสข้อมูล

  • หากต้องการเข้ารหัส XOR เอาต์พุต keystream ด้วยข้อความธรรมดา
  • ในการถอดรหัส XOR เอาต์พุต keystream ด้วย ciphertext

1. CipherSaber

CipherSaber (ซึ่งเป็นสิ่งที่เรากำลังนำไปใช้ในคำถามนี้) คือการเปลี่ยนแปลงของ RC4 / Arcfour ในสองวิธี:

10 ไบต์ IV / nonce

เมื่อเข้ารหัสข้อความควรได้รับ 10 ไบต์แบบสุ่มเช่นผ่าน/dev/urandomและเขียนลงใน 10 ไบต์แรกของเอาต์พุตที่เข้ารหัส เมื่อถอดรหัสข้อความ 10 ไบต์แรกของอินพุตคือ IV ที่ใช้เข้ารหัส

สเตจการติดตั้งคีย์ RC4 / Arcfour รันด้วยpassphrase || IVคีย์ซึ่งpassphraseเป็นวลีรหัสผ่านที่ผู้ใช้ระบุIVตามที่อธิบายไว้ข้างต้นและ||ต่อกัน ข้อความรหัสผ่านของ "Hello, world!" และ IV ของ "supercalif" (ไม่น่าเป็นไปได้นั่นคือ :-P) จะส่งผลให้เกิดคีย์ "Hello, world! supercalif"

การตั้งค่าคีย์ซ้ำหลายครั้ง

เพื่อช่วยป้องกันช่องโหว่ที่ทำให้การเข้ารหัส WEP เสียอย่างสมบูรณ์วงสับของขั้นตอนการตั้งค่าคีย์ของ RC4 จะถูกเรียกใช้ตามจำนวนครั้งที่ผู้ใช้ระบุ ค่าของjควรถูกเก็บไว้ระหว่างการวนซ้ำ

2. ทดสอบเวกเตอร์

นี่คือเวกเตอร์ทดสอบบางส่วนที่คุณสามารถใช้เพื่อทดสอบโปรแกรมของคุณ นอกจากนี้ossifrage คลื่นไส้ยังสร้างเครื่องมือการเข้ารหัสและถอดรหัส CipherSaberที่คุณสามารถใช้เพื่อตรวจสอบผลลัพธ์ของคุณ

คุณจะต้องใช้โปรแกรมเข้ารหัสเท่านั้น คุณไม่จำเป็นต้องจัดหาโปรแกรมถอดรหัส แต่ผลลัพธ์ของโปรแกรมเข้ารหัสของคุณจะต้องไปอย่างถูกต้องไปยังอินพุตดั้งเดิมเมื่อประมวลผลด้วยโปรแกรมถอดรหัสที่นำมาใช้อย่างถูกต้องโดยใช้คีย์ที่ถูกต้อง

คำตอบ:


7

Pyth, 100 ไบต์

$import os$KsM$os.urandom(10)$JuuXN@LN,T=+Z+@NT@+CMzKT)bGQU=b256=Z0sCM+K.exCb@=XJ=N@LJ,hk=+Z@Jhk)sNw

สคริปต์นี้ใช้$คำสั่งซึ่งอนุญาตให้เรียกใช้งานโค้ด Python เพื่อป้องกันการรันโค้ดที่เป็นอันตรายบนเซิร์ฟเวอร์คำสั่งนี้จะถูกปิดใช้งานในคอมไพเลอร์ออนไลน์ คุณต้องทำงานกับคอมไพเลอร์แบบ off-line ซึ่งคุณสามารถหาได้ที่นี่

อินพุตอยู่ในรูปแบบ:

secret key
5 (number of repeats)
secret message

โปรแกรมเอาต์พุตสตริงที่เข้ารหัสซึ่งอาจมีตัวอักษรที่ไม่สามารถพิมพ์ได้ หากคุณต้องการตรวจสอบโดยใช้เครื่องมือการเข้ารหัสและถอดรหัส CipherSaberคุณสามารถใช้รหัสต่อไปนี้ซึ่งแปลงสตริงเป็นชุดเลขฐานสิบหก

$import os$KsM$os.urandom(10)$JuuXN@LN,T=+Z+@NT@+CMzKT)bGQU=b256=Z0         
jdm.[2.HCd`0
sCM+K.exCb@=XJ=N@LJ,hk=+Z@Jhk)sNw

Pyth ไม่สนับสนุนหมายเลขปลอมเทียมที่ปลอดภัยแบบเข้ารหัสและนำเข้าจาก Python ราคา 25 ไบต์ โค้ดที่สั้นกว่าซึ่งใช้ตัวกำเนิด pseudorandom-number ของ Pyth's / Python และยังทำงานในคอมไพเลอร์ออนไลน์คือ:

KmO=b256TJuuXN@LN,T=+Z+@NT@+CMzKT)bGQUb=Z0sCM+K.exCb@=XJ=N@LJ,hk=+Z@Jhk)sNw

ลองออนไลน์: ส่งคืนสตริงหรือชุดตัวเลขฐานสิบหก

รหัสไม่มีอะไรพิเศษ เพียงการมอบหมายงานสกปรกจำนวนมากและนำผลการคำนวณกลับมาใช้ใหม่ทันทีและใช้เคล็ดลับlist-swapสองครั้ง

คำอธิบาย:

                                  implicit: z = 1st input (= key string)
                                  Q = 2nd input (number of repetitions)
$import os$KsM$os.urandom(10)$
$import os$                       import Python's os module
              $os.urandom(10)$    create 10 cryptographically secure 
                                  pseudo-random bytes
            sM                    convert them to ints
           K                      store them in K

JuuXN@LN,T=+Z+@NT@+CMzKT)bGQU=b256
                             =b256assign b with 256
 u                         QUb    start with G = [0, 1, ..., 255], 
                                  evaluate the following expression Q times and
                                  update G with the result each time:
  u                      bG         start with N = G, 
                                    for each T in [0, 1, ..., 255] evaluate the
                                    following expression and update N each time:
                   CMz                convert key to list of ints
                  +   K               extend it with K
                 @     T              take the Tth element (modulo length)
              @NT                     take the Tth element of N
             +                        add these two values
           +Z                         add Z (with is initially 0)
          =                           and update Z with the result
        ,T  Z                         make the pair of indices [T, Z] 
     @LN                              look-up their values in N
   XN                   )             and switch these two values in N
J                                 assign the result (the key setup) to J

=Z0                               set Z to 0

sCM+K.exCb@=XJ=N@LJ,hk=+Z@Jhk)sNw 
                                w read a string from input (message)
     .e                           map each index k, char b in message to:
                         @Jhk       look-up the (k+1)th element in J
                      =+Z           add it to Z and update Z
                   ,hk  Z           make the pair of indices [k+1,Z]
                @LJ                 look-up their values in J
              =N                    assign the result to N
            XJ N             )      swap these values in J
           =                        and update J with the result
          @  J                sN    take the sum(N)th element of J
        Cb                          convert b to int
       x                            bitwise xor of these two elements
   +K                             insert K at the beginning
 CM                               convert each element to char
s                                 sum them (generate a string)
                                  implicitly print

เห็นได้ชัดว่าในตัวฟังก์ชั่น Pyth ไม่ได้มีตัวเลข คุณสามารถเก็บรายการของคุณตามที่เป็นอยู่และจะไม่ผ่านการตรวจสอบสำหรับเห็บสีเขียวหรือคุณสามารถสร้างเวอร์ชันที่ใช้urandom(ซึ่งอาจเป็นรายการแยกต่างหากหากคุณต้องการ) หากคุณสนใจเกี่ยวกับ "การชนะ" :-)
Chris Jester-Young

@ ChrisJester-Young ขออภัยด้วย ฉันไม่คิดว่าตัวสร้างหมายเลขสุ่มของไพ ธ อนนั้นไม่ปลอดภัย แก้ไขให้เป็นค่า 25 ไบต์
Jakube

4

Python 2 - 373 350 326 317 ไบต์

Pyth อาจจะมาในภายหลัง กำหนดหนึ่งฟังก์ชันc(p,d,r,m)ซึ่งรับรายการไบต์สำหรับวลีรหัสผ่านและข้อมูลและ int สำหรับการทำซ้ำและโหมดที่เข้ารหัสเมื่อ 1 และถอดรหัสเมื่อ 0 เนื่องจากนี่เป็นความแตกต่างเพียงอย่างเดียวในการจัดการกับ IV ส่งคืนรายการไบต์

import os
B=256
def c(p,d,r,m):
    if m:v=map(ord,os.urandom(10))
    else:v,d=d[:10],d[10:]
    p+=v;S=range(B);T=(p*B)[:B];j=0;exec"for i in range(B):j=(j+S[i]+T[i])%B;S[i],S[j]=S[j],S[i]\n"*r;o=[];i=j=0
    for b in d:i=-~i%B;j=(j+S[i])%B;S[i],S[j]=S[j],S[i];k=(S[i]+S[j])%B;o+=[S[k]^b]
    return v+o if m else o

นี่คือฟังก์ชั่นการทดสอบรหัส / ผู้ช่วย:

phrase = "hello"
text = "Mary had a little lamb, little lamb, little lamb"
N = 5

def make_bytes(string):
    return map(ord, string)

def make_string(bytes):
    return "".join(map(chr, bytes))

def make_hex(bytes):
    return " ".join("%02x" % i for i in bytes)

def from_hex(hex_str):
    return [int(i, 16) for i in hex_str.split()]

cipher = c(make_bytes(phrase), make_bytes(text), N, 1)
print make_hex(cipher)
plain = c(make_bytes(phrase), cipher, N, 0)
print make_string(plain)

คุณจะต้องเขียนโปรแกรมเข้ารหัส ดังนั้นคุณสามารถลบelse:v,d=d[:10],d[10:]ส่วน
Jakube

3

Ruby - 263 ตัวอักษร

นี่คือทับทิมของฉันตอบคำถามเดิมใน stackoverflow ย้อนกลับไปในปี 2010! มันเป็นเครื่องเข้ารหัสและถอดรหัสทั้งหมดในโปรแกรมเดียว

พารามิเตอร์:
อีหรือ d (สำหรับการเข้ารหัสหรือถอดรหัส)
ที่สำคัญ
จำนวนครั้ง

$ ruby saber.rb e gnibbler 10 < in.txt | ruby saber.rb d gnibbler 10

o,k,l=ARGV;print o<'e'?(v=STDIN.read(10))*0:v=(0..9).map{rand(256).chr}.join;j=0;E=255
S=Array 0..255;(S*l.to_i).each{|i|j=j+S[i]+((k+v)*E)[i].ord&E;S[i],S[j]=S[j],S[i]};i=j=0
STDIN.each_byte{|c|i=i+1&E;j=j+S[i]&E;S[i],S[j]=S[j],S[i];print (c^S[S[i]+S[j]&E]).chr}

2

C, 312 ไบต์

ยอมรับคีย์และการผสมการวนซ้ำของคีย์ในบรรทัดคำสั่งจากนั้นเข้ารหัสทุกอย่างใน stdin ไปยัง stdout สิ่งนี้ใช้ฟังก์ชันไลบรารี BSD / Darwin arc4random()ซึ่งเป็น PRNG ที่อ้างอิง RC4 มันเมล็ดตัวเองโดยอัตโนมัติดังนั้นผลลัพธ์จะแตกต่างกันทุกครั้ง

unsigned char n,i,j,q,x,t,s[256],k[256];main(int c,char**v){for(strcpy(k,v[1]),n=strlen(k);x<10;x++)putchar(k[n++]=arc4random());do{s[i]=i;}while(++i);for(x=atoi(v[2]);x--;)do{t=s[i];s[i]=s[j+=s[i]+k[i%n]];s[j]=t;}while(++i);for(;(c=getchar())>0;){q+=s[++i];t=s[i];s[i]=s[q];s[q]=t;t=s[i]+s[q];putchar(c^s[t]);}}

รุ่น Tidier:

unsigned char n,i,j,q,x,t,s[256],k[256];
main(int c,char**v) {
  for (strcpy(k,v[1]),n=strlen(k);x<10;x++) putchar(k[n++]=arc4random());
  do {
    s[i]=i;
  }
  while(++i);
  for (x=atoi(v[2]);x--;) do {
    t=s[i];
    s[i]=s[j+=s[i]+k[i%n]];
    s[j]=t;
  }
  while (++i);
  for (;(c=getchar())>0;) {
    q+=s[++i];
    t=s[i];
    s[i]=s[q];
    s[q]=t;
    t=s[i]+s[q];
    putchar(c^s[t]);
  }
}

ตัวอย่าง:

$ echo -n 'Ciphersaber' | ./csgolf 'hello' 20 | xxd -p
0f6257c330e5e01c3eab07bc9cb4ee4c3eaa514a85

1

Python 266 ตัวอักษร

นี่คือคำตอบของ Python ของฉันสำหรับคำถามดั้งเดิมเกี่ยวกับ stackoverflow ย้อนกลับไปในปี 2010! มันเป็นเครื่องเข้ารหัสและถอดรหัสทั้งหมดในโปรแกรมเดียว

พารามิเตอร์:
อีหรือ d (สำหรับการเข้ารหัสหรือถอดรหัส)
ที่สำคัญ
จำนวนครั้ง

$ python saber.py e gnibbler 10 < in.txt | python saber.py d gnibbler 10

รุ่นนี้พยายามรวม rc4 2 ลูปเข้าด้วยกัน (บันทึก 11 ไบต์จนถึง ... )

import os,sys;X,Y=sys.stdin.read,os.write;_,o,k,l=sys.argv;p='d'<o
V=(X,os.urandom)[p](10);Y(1,V*p);E,S=255,range(256)
for q in S*int(l),X():
 t=q<'';j=0;i=-t
 for c in q:i=i+1&E;j=j+S[i]+t*ord(((k+V)*E)[i])&E;S[i],S[j]=S[j],S[i];t or Y(1,chr(ord(c)^S[S[i]+S[j]&E]))
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.