This is a fuction of encrypion of DCA toy cipher1. I tried so any time but don't know what wrong with my code. Please help me solving it.
SBox = [b'0110', b'0100', b'1100', b'0101', b'0000', b'0111', b'0010', b'1110', b'0001', b'1111', b'0011', b'1101', b'1000', b'1010', b'1001', b'1011']
def dca_tc1_encrypt(plaintext,key):
#Split the 2 bit key into two, 16 bit round keys key_0 = key[:16] key_1 = key[16:]
#XOR the plaintext against k0 xor_key_0 = int(plaintext,2) ^ int(key_0,2)
#get the binary representation and split it into 4 blocks of 4 bits bin_value = f'{bin(xor_key_0)[2:]}'.zfill(16) blocks = [bin_value[:4], bin_value[4:8],bin_value[8:12],bin_value[12:16] ]
#print(blocks) #look at the blocks
#iterate over the blocks and get the value from the SBox look up
sbox = b'' for block in blocks:
sbox = sbox + (SBox[int(block,2)])
#print(sbox) #check the new SBox values
#XOR against k1 ciphertext = int(sbox,2) ^ int(key_1,2) #return the ciphertext as a binary string return f'{bin(ciphertext)[2:]}'.zfill(16)
#Example use plaintext = b'1000101000001011' key = b'01111001101110110101001001110010'
print(f'Starting Plaintext: {plaintext}') ciphertext = dca_tc1_encrypt(plaintext,key) print(f'Ciphertext: {ciphertext}')
The program output should be
Program Output
Starting Plaintext: b'1001001001000101'
Ciphertext: 0001001000010100
Related
I am trying to do a Vigenere Cipher decrypter. The message gets decrypted with the current code that I have written. However, it does not take punctuation and whitespace into consideration. How do I make it consider these two components? Below is my code:
vigenered_message = 'dfc jhjj ifyh yf hrfgiv xulk? vmph bfzo! qtl eeh gvkszlfl yyvww kpi hpuvzx dl tzcgrywrxll!'
keyword = 'friends'
def vigenere_decrypt(encrypted_vigener, keyword):
keyword_length = len(keyword)
keyword_as_int = [ord(i) for i in keyword]
encrypted_vigener_int = [ord(i) for i in encrypted_vigener]
plaintext = ''
for i in range(len(encrypted_vigener_int)):
value = (encrypted_vigener_int[i] - keyword_as_int[i % keyword_length]) % 26
plaintext += chr(value + 65)
return plaintext
print(vigenere_decrypt(vigenered_message, keyword))
This offset of this should be: 'YOU WERE ABLE TO DECODE THIS? NICE WORK!
YOU ARE BECOMING QUITE THE EXPERT AT CRYPTOGRAPHY'
TRY THIS
vigenered_message = r'dfc jhjj ifyh yf hrfgiv xulk? vmph bfzo! qtl eeh gvkszlfl yyvww kpi hpuvzx dl tzcgrywrxll!'
keyword = 'friends'
def vigenere_decrypt(encrypted_vigener, keyword):
keyword_length = len(keyword)
keyword_as_int = [ord(i) for i in keyword]
encrypted_vigener_int = [ord(i) for i in encrypted_vigener]
plaintext = ''
for i in range(len(encrypted_vigener_int)):
if vigenered_message[i].isalpha():
value = (encrypted_vigener_int[i] - keyword_as_int[i % keyword_length]) % 26
plaintext += chr(value + 65)
else:
plaintext += vigenered_message[i]
return plaintext
print(vigenere_decrypt(vigenered_message, keyword))
OUTPUT:
YOU WERE ABLE TO DECODE THIS? NICE WORK! YOU ARE BECOMING QUITE THE EXPERT AT CRYTOGRAPHY!
Just a sidenote, you should assign string to a variable in raw format otherwise characters like \,",' inside your string, can create interruptions in the flow of program.
USE THIS:
vigenered_message = r'dfc jhjj ifyh yf hrfgiv xulk? vmph bfzo! qtl eeh gvkszlfl yyvww kpi hpuvzx dl tzcgrywrxll!'
NOT THIS:
vigenered_message = 'dfc jhjj ifyh yf hrfgiv xulk? vmph bfzo! qtl eeh gvkszlfl yyvww kpi hpuvzx dl tzcgrywrxll!'
I have the below java code to encode a string with a pass key
public static String encrypt(String message, String passkey) throws Exception {
final MessageDigest md = MessageDigest.getInstance("SHA-1");
final byte[] digestOfPassword = md.digest(passkey.getBytes("utf-8"));
final byte[] keyBytes = ( byte[])resizeArray(digestOfPassword, 24);
for (int j = 0, k = 16; j < 8;) {
keyBytes[k++] = keyBytes[j++];
}
final SecretKey key = new SecretKeySpec(keyBytes, "DESede");
final IvParameterSpec iv = new IvParameterSpec(new byte[8]);
final Cipher cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, key, iv);
final byte[] plainTextBytes = message.getBytes("utf-8");
final byte[] cipherText = cipher.doFinal(plainTextBytes);
String encryptedString = Base64.encodeBase64String(cipherText);
return encryptedString;
}
Now I converted the same code into python(Python 2.7), and I tried as below.
def encrypt(message, passkey):
hash_object = hashlib.sha1(passkey.encode("utf-8"))
digested_passkey = hash_object.digest() //hashing
key24 = "{: <24}".format(digested_passkey) // for resizing the byte array to size 24
import pyDes
des = pyDes.des(key24);(at this line I m getting the error "Invalid DES key size. Key must be exactly 8 bytes long".
message = message.encode('utf-8')
message = message + (16 - len(message) % 16) * chr(16 - len(message) % 16) // this is for padding
iv = Random.new().read(AES.block_size)
cipher = AES.new(des, AES.MODE_CBC, iv)
return base64.b64encode(iv + cipher.encrypt(message))
At the line des = pyDes.des(key24), I am getting the error "Invalid DES key size. Key must be exactly 8 bytes long."
The passkey that I sent as parameter is "f!16*hw$sda66"
Can anyone please let me know if there is anything wrong with the line
des = pyDes.des(key24)
I think the reason you are getting this error is because the Class initialisation method is expecting the key to be exactly 8, if it's anything else it raises the error you are seeing, this is the init of the class you are calling from pyDes:
# Initialisation
def __init__(self, key, mode=ECB, IV=None, pad=None, padmode=PAD_NORMAL):
# Sanity checking of arguments.
if len(key) != 8:
raise ValueError("Invalid DES key size. Key must be exactly 8 bytes long.")
If you do this for debugging:
def encrypt(message, passkey):
hash_object = hashlib.sha1(passkey.encode("utf-8"))
digested_passkey = hash_object.digest() //hashing
key24 = "{: <24}".format(digested_passkey)
print len(key24)
You will see the length of the key is 24, which is why I think it is not being accepted.
I might be wrong but at a quick glance that looks like the issue.
I have the same issue as this question but unfortunately there was no answer on it.
I have the following objective-c code to encrypt using CCCrypt:
(NSData *)doCrypt:(NSData *)data usingKey:(NSData *)key withInitialVector:(NSData *)iv mode:(int)mode error: (NSError *)error
{
int buffersize = 0;
if(data.length % 16 == 0) { buffersize = data.length + 16; }
else { buffersize = (data.length / 16 + 1) * 16 + 16; }
// int buffersize = (data.length <= 16) ? 16 : data.length;
size_t numBytesEncrypted = 0;
void *buffer = malloc(buffersize * sizeof(uint8_t));
CCCryptorStatus result = CCCrypt(mode, 0x0, 0x1, [key bytes], [key length], [iv bytes], [data bytes], [data length], buffer, buffersize, &numBytesEncrypted);
return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted freeWhenDone:YES];
}
I use kCCAlgorithmAES128 with kCCOptionPKCS7Padding as options and call the function with [Cryptor doCrypt:data usingKey:key withInitialVector:nil mode:0x0 error:nil];
Now I would like to decrypt it using python and to do so I have the following code:
def decrypt(self, data, key):
iv = '\x00' * 16
encoder = PKCS7Encoder()
padded_text = encoder.encode(data)
mode = AES.MODE_CBC
cipher = AES.new(key, mode, iv)
decoded = cipher.decrypt(padded_text)
return decoded
The PKCS7Encoder looks like this:
class PKCS7Encoder():
"""
Technique for padding a string as defined in RFC 2315, section 10.3,
note #2
"""
class InvalidBlockSizeError(Exception):
"""Raised for invalid block sizes"""
pass
def __init__(self, block_size=16):
if block_size < 2 or block_size > 255:
raise PKCS7Encoder.InvalidBlockSizeError('The block size must be ' \
'between 2 and 255, inclusive')
self.block_size = block_size
def encode(self, text):
text_length = len(text)
amount_to_pad = self.block_size - (text_length % self.block_size)
if amount_to_pad == 0:
amount_to_pad = self.block_size
pad = chr(amount_to_pad)
return text + pad * amount_to_pad
def decode(self, text):
pad = ord(text[-1])
return text[:-pad]
Yet whenever I call the decrypt() function, it returns garbage. Am I missing something or having a wrong option enabled somewhere?
Example in and output:
NSData *keyData = [[NSData alloc] initWithRandomData:16];
NSLog(#"key: %#", [keyData hex]);
NSString *str = #"abcdefghijklmno";
NSLog(#"str: %#", str);
NSData *encrypted = [Cryptor encrypt:[str dataUsingEncoding:NSUTF8StringEncoding] usingKey:keyData];
NSLog(#"encrypted str: %#", [encrypted hex]);
Gives:
key: 08b6cb24aaec7d0229312195e43ed829
str: a
encrypted str: 52d61265d22a05efee2c8c0c6cd49e9a
And python:
cryptor = Cryptor()
encrypted_hex_string = "52d61265d22a05efee2c8c0c6cd49e9a"
hex_key = "08b6cb24aaec7d0229312195e43ed829"
print cryptor.decrypt(encrypted_hex_string.decode("hex"), hex_key.decode("hex"))
Result:
láz
Which is weird, but if dump the hex I get 610f0f0f0f0f0f0f0f0f0f0f0f0f0f0fb02b09fd58cccf04f042e2c90d6ce17a and 61 = a so I think it just shows wrong.
A bigger input:
key: 08b6cb24aaec7d0229312195e43ed829
str: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
encrypted str: 783fce3eca7ebe60d58b01da3d90105a93bf2d659cfcffc1c2b7f7be7cc0af4016b310551965526ac211f4d6168e3cc5
Result:
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaôNÍ“ƒ˜�Üšw6C%
Here you see that the a's are printed with garbage... so I assume this is a padding error or something like that
The IV is nill at the iOs side and 16x 0's at the Python side (see the code)
Your decryption: aes_decrypt(pkcs7_pad(ciphertext))
Correct decryption: pkcs7_unpad(aes_decrypt(ciphertext))
It has to be done this way, because AES in CBC mode expects plaintexts of a multiple of the block size, but you generally want to encrypt arbitrary plaintexts. Therefore, you need to apply the padding before encryption and remove the padding after decryption.
Keep in mind that a - (b % a) cannot be 0 for any (positive) value of a or b. This means that
if amount_to_pad == 0:
amount_to_pad = self.block_size
is unreachable code and can be removed. Good thing is that a - (b % a) already does what you wanted to do with the if block.
You also should extend the unpad (decode) function to actually check whether every padding byte is the same byte. You should also check that the every padding byte is not zero or larger than the block size.
I have a program in python that takes two strings. One is the plain text string, another is the cipher key. what it does is go over each of the characters and xors the bits with the cipher characters. But when going back and forth a few of the letter do not seem to change properly. Here is the code:
//turns int into bin string length 8
def bitString(n):
bin_string = bin(n)[2:]
bin_string = ("0" * (8 - len(bin_string))) + bin_string
return bin_string
//xors the bits
def bitXOR(b0, b1):
nb = ""
for x in range(min(len(b0), len(b1))):
nb += "0" if b0[x] == b1[x] else "1"
return nb
//takes 2 chars, turns them into bin strings, xors them, then returns the new char
def cypherChar(c0, c1):
return chr(int(bitXOR(bitString(ord(c0)), bitString(ord(c1))), 2))
//takes s0 (the plaintext) and encrypts it using the cipher key (s1)
def cypherString(s0, s1):
ns = ""
for x in range(len(s0)):
ns += cypherChar(s0[x], s1[x%len(s1)])
return ns
For example sometimes in a long string the word 'test' will cipher back into 'eest', and stuff like that
I have checked over the code a dozen times and I can't figure out whats causing some of the characters to change. Is it possible some characters just behave strangely?
EDIT:
example:
This is a test
Due to the fact that in the last test
Some symbols: !##$%^&*()
were not changed properly
I am retesting
END
using the cipher key : 'cypher key'
translates back to :
This is a test
Due to toe aact that in the last sest
Some symbols: !##$%^&*()
were not changed properly
I am retestiig
END
Sorry it its a little messy, I put it together real quick
from binascii import hexlify, unhexlify
from sys import version_info
def bit_string(string):
if version_info >= (3, 0):
return bin(int.from_bytes(string.encode(), 'big'))
else:
return bin(int(hexlify(string), 16))
def bitXOR_encrypt(plain_text, key):
encrypted_list = []
for j in range(2, len(plain_text)):
encrypted_list.append(int(plain_text[j]) ^ int(key[j])) #Assume the key and string are the same length
return encrypted_list
def decrypt(cipher_text, key):
decrypted_list = []
for j in range(2, len(cipher_text)): #or xrange
decrypted_list.append(int(cipher_text[j]) ^ int(key[j])) #Again assumes key is the same length as the string
decrypted_list = [str(i) for i in decrypted_list]
add_binary = "0b" + "".join(decrypted_list)
decrypted_string = int(add_binary, 2)
if version_info >= (3, 0):
message = decrypted_string.to_bytes((decrypted_string.bit_length() + 7) // 8, 'big').decode()
else:
message = unhexlify('%x' % decrypted_string)
return message
def main():
plain_text = "Hello"
plain_text_to_bits = bit_string(plain_text)
key_to_bits = bit_string("candy")
#Encrypt
cipher_text = bitXOR_encrypt(plain_text_to_bits, key_to_bits)
#make Strings
cipher_text_string = "".join([str(i) for i in cipher_text])
key_string = "".join([str(i) for i in key_to_bits])
#Decrypt
decrypted_string = decrypt("0B"+cipher_text_string, key_string)
print("plain text: %s" % plain_text)
print("plain text to bits: % s" % plain_text_to_bits)
print("key string in bits: %s" % key_string)
print("Ciphered Message: %s" %cipher_text_string)
print("Decrypted String: %s" % decrypted_string)
main()
for more details or example code you can visit my repository either on github
https://github.com/marcsantiago/one_time_pad_encryption
Also, I know that in this example the key is the same length as the string. If you want to use a string that is smaller than the string try wrapping it like in a vigenere cipher (http://en.wikipedia.org/wiki/Vigenère_cipher)
I think you are overcomplicating things:
def charxor(s1, s2):
return chr(ord(s1) ^ ord(s2))
def wordxor(w1, w2):
return ''.join(charxor(w1[i], w2[i]) for i in range(min(len(w1), len(w2))))
word = 'test'
key = 'what'
cyphered = wordxor(word, key)
uncyphered = wordxor(cyphered, key)
print(repr(cyphered))
print(uncyphered)
You get
'\x03\r\x12\x00'
test
There is a fairly good explanation of Python's bit arithmetic in How do you get the logical xor of two variables in Python?
I could find nothing wrong with the results of your functions when testing with your input data and key. To demonstrate, you could try this test code which should not fail:
import random
def random_string(n):
return ''.join(chr(random.getrandbits(8)) for _ in range(n))
for i in range(1000):
plaintext = random_string(500)
key = random_string(random.randrange(1,100))
ciphertext = cypherString(plaintext, key)
assert cypherString(ciphertext, key) == plaintext
If you can provide a definitive sample of plain text, key, and cipher text that fails, I can look further.
A month ago, i asked this about multiplexing a string of numbers with 4 7-segment displays. But now, I'm trying to update the code to multiplex a string of letters using 7 7-segment displays in python.
This is the new circuit. When i send data using the parallel port, the Latch Enable receives the most significant bit (pin 9). In the second latch, the Latch Enable receives it also but negated, that is the reason of the 7404.
That is either address is set (/LE==False) or data is set (/LE=True).
This is what I'm trying to do. The 'X' represents that the 7-segment display is off. But can't archive it.
XXXXXXX
XXXXXXS
XXXXXST
XXXXSTA
XXXSTAC
XXSTACK
XSTACKX
STACKX0
TACKX0V
ACKX0V3
CKX0V3R
KX0V3RF
X0VERFL
0VERFL0
VERFL0W
ERFL0WX
RFL0WXX
FL0WXXX
L0WXXXX
0WXXXXX
WXXXXXX
XXXXXXX
That would be the output for the string "STACK 0V3RFL0W".
Also the past code:
import sys
import parallel
class Display(object):
def __init__(self):
'''Init and blank the "display".'''
self.display = [' '] * 4
self._update()
def setData(self,data):
'''Bits 0-3 are the "value".
Bits 4-7 are positions 0-3 (first-to-last).
'''
self.display = [' '] * 4
value = data & 0xF
if data & 0x10:
self.display[0] = str(value)
if data & 0x20:
self.display[1] = str(value)
if data & 0x40:
self.display[2] = str(value)
if data & 0x80:
self.display[3] = str(value)
self._update()
def _update(self):
'''Write over the same four terminal positions each time.'''
sys.stdout.write(''.join(self.display) + '\r')
if __name__ == '__main__':
p = Display()
pp=parallel.Parallel()
nums = raw_input("Enter a string of numbers: ")
# Shift over the steam four-at-a-time.
stream = 'XXXX' + nums + 'XXXX'
data = [0] * 4
for i in range(len(stream)-3):
# Precompute data
for pos in range(4):
value = stream[i+pos]
data[pos] = 0 if value == 'X' else (1<<(pos+4)) + int(value)
# "Flicker" the display...
for delay in xrange(1000):
# Display each position briefly.
for d in data:
pp.setData(d)
# Clear the display when done
p.setData(0)
Algorithm outline:
string = "07831505"
while True:
for i in range(7):
# switch display `i` on
notlatch.set(True)
data.set(1 << i)
notlatch.set(False)
time.sleep(<very little>)
notlatch.set(True)
# display character on display `i`
data.set(char_to_7segment(string[i]))
time.sleep(0.01)