def testSessionEncryptAndDecrypt(self): encrypter = keyczar.Encrypter.Read(_get_test_dir("rsa")) session_encrypter = keyczar.SessionEncrypter(encrypter); session_material = session_encrypter.session_material ciphertext = session_encrypter.Encrypt(self.input) # Verify that session_material and ciphertext are base64-encoded: Decoding will fail with # high probability if they're not. util.Base64WSDecode(session_material) util.Base64WSDecode(ciphertext) crypter = keyczar.Crypter.Read(_get_test_dir("rsa")) session_decrypter = keyczar.SessionDecrypter(crypter, session_material) plaintext = session_decrypter.Decrypt(ciphertext) self.assertEqual(self.input, plaintext)
def testUnencodedUnversionedVerify(self): (signer, sig) = self.__unversionedSignInput("hmac") unencoded_sig = util.Base64WSDecode(sig) self.assertTrue(signer.Verify(self.input, unencoded_sig, None)) self.assertFalse(signer.Verify(self.input, unencoded_sig)) self.assertFalse(signer.Verify(self.input, sig, None)) self.assertTrue(signer.Verify(self.input, sig))
def Verify(self, data, sig): """ Verifies whether the signature corresponds to the given data. This is a stanard signature (i.e. HMAC-SHA1, RSA-SHA1, DSA-SHA1) that contains no version information, so this will try to verify with each key in a keyset. @param data: message that has been signed with sig @type data: string @param sig: Base64 string formatted as Header|Signature @type sig: string @return: True if sig corresponds to data, False otherwise. @rtype: boolean """ sig_bytes = util.Base64WSDecode(sig) for version in self.versions: key = self._keys[version] # Try to verify with each key result = key.Verify(util.RawBytes(data), sig_bytes) if result: return True # None of the keys verified the signature return False
def AttachedVerify(self, signed_data, nonce): """ Verifies the signature in the signed blob corresponds to the data in the signed blob and the provided nonce, and returns the data. @param signed_data: the blob, produced by AttachedSign, containing data and signature. @type signed_data: string @param nonce: Nonce string that was used when the signature was generated. If the provided value doesn't match, verification will fail. @type sig: string @return: If verification succeeds, the extracted data will be returned, otherwise, None @rtype: string """ decoded_data = util.Base64WSDecode(signed_data) reader = util.BytesReader(decoded_data) writer, getoutput = util.BytesWriter() nonce = util.RawBytes(nonce) if self.AttachedVerifyIO(reader, writer, nonce): return util.RawString(getoutput()) return None
def __testStandardEncryptAndStreamDecrypt(self, subdir, input_data, stream_buffer_size, len_to_read, stream_source ): crypter = keyczar.Crypter.Read(os.path.join(TEST_DATA, subdir)) ciphertext = crypter.Encrypt(input_data) ciphertext_stream = StringIO.StringIO(ciphertext) if stream_source is None: decoder = None ciphertext_stream = StringIO.StringIO(util.Base64WSDecode(ciphertext)) else: decoder = util.IncrementalBase64WSStreamReader decryption_stream = crypter.CreateDecryptingStreamReader( ciphertext_stream, decoder=decoder, buffer_size=stream_buffer_size) plaintext = self.__readFromStream(decryption_stream, len_to_read) self.assertEquals(len(input_data), len(plaintext), 'Wrong length for buffer:%d, read len:%d' %(stream_buffer_size, len_to_read)) self.assertEquals(input_data, plaintext, 'Not equals for buffer:%d, read len:%d' %(stream_buffer_size, len_to_read))
class Key(object): """Parent class for Keyczar Keys.""" def __init__(self, key_type): self.type = key_type self.__size = self.type.default_size # initially default def __eq__(self, other): return (self.type == other.type and self.size == other.size and self.key_string == other.key_string) def __SetSize(self, new_size): if self.type.IsValidSize(new_size): self.__size = new_size def _GetKeyString(self): """Return the key as a string. Abstract method.""" def __GetKeyString(self): """Indirect getter for the key string.""" return self._GetKeyString() def _Hash(self): """ Compute and return the hash_id id of this key. Can override default hash_id. """ fullhash = util.PrefixHash(self.key_bytes) return util.Base64WSEncode(fullhash[:constants.KEY_HASH_SIZE]) def __Hash(self): """Indirect getter for hash_id.""" return self._Hash() def _FallbackHashes(self): return [] def __FallbackHashes(self): """Indirect getter for fallback_hash_id.""" return self._FallbackHashes() hash_id = property(__Hash, doc="""The hash_id id of the key.""") fallback_hash_ids = property(__FallbackHashes, doc="""The fallback hash ids from other bad implementations""") size = property(lambda self: self.__size, __SetSize, doc="""The size of the key in bits.""") key_string = property(__GetKeyString, doc="""The key as a Base64 string.""") key_bytes = property(lambda self: util.Base64WSDecode(self.key_string), doc="""The key as bytes.""") def Header(self): """ Return the 5-byte header string including version byte, 4-byte hash_id. """ return (bytes(bytearray([constants.VERSION])) + util.Base64WSDecode(self.hash_id))
def Read(key): """ Reads a RSA public key from a JSON string representation of it. @param key: a JSON representation of a RSA public key @type key: string @return: a RSA public key @rtype: L{RsaPublicKey} """ rsa = json.loads(key) params = {'modulus': util.Base64WSDecode(rsa['modulus']), 'publicExponent': util.Base64WSDecode(rsa['publicExponent'])} pubkey = RSA.construct((util.BytesToLong(params['modulus']), util.BytesToLong(params['publicExponent']))) return RsaPublicKey(params, pubkey, rsa['size'])
def testBadAesCiphertexts(self): crypter = keyczar.Crypter.Read(os.path.join(TEST_DATA, "aes")) ciphertext = util.Base64WSDecode(crypter.Encrypt(self.input_data)) bad = util.Base64WSEncode(chr(0)) char = chr(ord(ciphertext[2]) ^ 44) ciphertext = util.Base64WSEncode(ciphertext[:2]+char+ciphertext[3:]) self.assertRaises(errors.ShortCiphertextError, crypter.Decrypt, bad) self.assertRaises(errors.KeyNotFoundError, crypter.Decrypt, ciphertext)
def testUnencodedAttachedVerify(self): (signer, sig) = self.__attachedSignInput("hmac", "nonce") unencoded_sig = util.Base64WSDecode(sig) self.assertTrue(signer.AttachedVerify(unencoded_sig, "nonce", None)) try: signer.Verify(self.input, unencoded_sig) raise Exception("Verify should throw a Decoding error") except errors.Base64DecodingError, e: pass
def LoadJsonSession(json_session_data): """ Constructs and returns a new _Session instance, initialized with the key and nonce extracted from the provided json_session_data, which must have been produced by _Session.json. """ json_dict = json.loads(json_session_data) aes_key_string = json.dumps(json_dict['key']) return _Session.__Create(keys.AesKey.Read(aes_key_string), util.Base64WSDecode(json_dict['nonce']))
def __testDecryptStream(self, subdir, reader, input_data, stream_buffer_size, len_to_read, stream_source): """NOTE: input_data ignored here as we don't have a valid ".out" for random data""" path = os.path.join(TEST_DATA, subdir) if reader: crypter = keyczar.Crypter(reader) else: crypter = keyczar.Crypter.Read(path) active_ciphertext = util.ReadFile(os.path.join(path, "1.out")) if stream_source is None: decoder = None active_ciphertext = util.Base64WSDecode(active_ciphertext) else: decoder = util.IncrementalBase64WSStreamReader decryption_stream = crypter.CreateDecryptingStreamReader( StringIO.StringIO(active_ciphertext), decoder=decoder, buffer_size=stream_buffer_size) plaintext = self.__readFromStream(decryption_stream, len_to_read) self.assertEquals(self.input_data, plaintext, 'Active not equals for buffer:%d, read len:%d, src:%s' %( stream_buffer_size, len_to_read, stream_source )) primary_ciphertext = util.ReadFile(os.path.join(path, "2.out")) if stream_source is None: primary_ciphertext = util.Base64WSDecode(primary_ciphertext) decryption_stream = crypter.CreateDecryptingStreamReader( StringIO.StringIO(primary_ciphertext), decoder=decoder, buffer_size=stream_buffer_size) plaintext = self.__readFromStream(decryption_stream, len_to_read) self.assertEquals(self.input_data, plaintext, 'Primary not equals for buffer:%d, read len:%d, src:%s' %( stream_buffer_size, len_to_read, stream_source ))
def Read(key): """ Reads a DSA public key from a JSON string representation of it. @param key: a JSON representation of a DSA public key @type key: string @return: a DSA public key @rtype: L{DsaPublicKey} """ dsa = json.loads(key) params = {'y': util.Base64WSDecode(dsa['y']), 'p': util.Base64WSDecode(dsa['p']), 'g': util.Base64WSDecode(dsa['g']), 'q': util.Base64WSDecode(dsa['q'])} pubkey = DSA.construct((util.BytesToLong(params['y']), util.BytesToLong(params['g']), util.BytesToLong(params['p']), util.BytesToLong(params['q']))) return DsaPublicKey(params, pubkey, dsa['size'])
def testHmacBadSigs(self): (signer, sig) = self.__signInput("hmac") sig_bytes = util.Base64WSDecode(sig) self.assertRaises(errors.ShortSignatureError, signer.Verify, self.input, "AB") bad_sig = util.Base64WSEncode(chr(23) + sig_bytes[1:]) self.assertRaises(errors.BadVersionError, signer.Verify, self.input, bad_sig) char = chr(ord(sig_bytes[1]) ^ 45) # Munge key hash info in sig bad_sig = util.Base64WSEncode(sig_bytes[0] + char + sig_bytes[2:]) self.assertRaises(errors.KeyNotFoundError, signer.Verify, self.input, bad_sig)
def Read(key): """ Reads a RSA private key from a JSON string representation of it. @param key: a JSON representation of a RSA private key @type key: string @return: a RSA private key @rtype: L{RsaPrivateKey} """ rsa = json.loads(key) pub = RsaPublicKey.Read(json.dumps(rsa['publicKey'])) params = {'privateExponent': util.Base64WSDecode(rsa['privateExponent']), 'primeP': util.Base64WSDecode(rsa['primeP']), 'primeQ': util.Base64WSDecode(rsa['primeQ']), 'primeExponentP': util.Base64WSDecode(rsa['primeExponentP']), 'primeExponentQ': util.Base64WSDecode(rsa['primeExponentQ']), 'crtCoefficient': util.Base64WSDecode(rsa['crtCoefficient']) } key = RSA.construct((util.BytesToLong(pub.params['modulus']), util.BytesToLong(pub.params['publicExponent']), util.BytesToLong(params['privateExponent']), util.BytesToLong(params['primeQ']), util.BytesToLong(params['primeP']), util.BytesToLong(params['crtCoefficient']))) return RsaPrivateKey(params, pub, key, rsa['size'])
def Decrypt(self, signed_ciphertext): """ Verifies the signature on the given ciphertext and, if successful, decrypts it and returns the decrypted plaintext. If verification fails, returns None. """ reader = util.BytesReader(util.Base64WSDecode(signed_ciphertext)) writer, getoutput = util.BytesWriter() if not self._verifier.AttachedVerifyIO(reader, writer, self._session.nonce): return None return self._session.crypter.Decrypt(getoutput(), None)
def testSimulateDecrypter(self): enc_data = util.RawBytes( 'AJehaFGwoOrkzpDCnF1zqIi721eCOMYWRmLyRyn3hxyhh_mYwpnDN6jKN057gr5lz' \ 'APFYhq9zoDwFMaGMEipEl__ECOZGeaxWw') expected_result = util.Base64WSDecode(enc_data) stream = util.IncrementalBase64WSStreamReader(io.BytesIO(enc_data)) result = stream.read(5) result += stream.read(15) read_data = True while read_data: read_data = stream.read(4096) result += read_data self.assertEqual(result, expected_result)
def testSessionEncryptAndDecrypt(self): encrypter = keyczar.Encrypter.Read(_get_test_dir("rsa")) session_encrypter = keyczar.SessionEncrypter(encrypter) session_material = session_encrypter.session_material ciphertext = session_encrypter.Encrypt(self.input) # Verify that session_material and ciphertext are base64-encoded: Decoding will fail with # high probability if they're not. util.Base64WSDecode(session_material) util.Base64WSDecode(ciphertext) crypter = keyczar.Crypter.Read(_get_test_dir("rsa")) session_decrypter = keyczar.SessionDecrypter(crypter, session_material) plaintext = session_decrypter.Decrypt(ciphertext) self.assertEqual(self.input, plaintext) # Test raw encryption/decryption raw_ciphertext = session_encrypter.Encrypt(self.input, encoder=None) # The headers should be equal; ciphertext will be different due to IVs self.assertEqual( util.Base64WSDecode(ciphertext)[0:5], raw_ciphertext[0:5]) plaintext = session_decrypter.Decrypt(raw_ciphertext, decoder=None) self.assertEqual(self.input, plaintext)
def testRsaSignatureLengthPadding(self): """ Checks that byte strings are padded with 0s in front for small signatures. Generates strings of 'a's and signs them until a signature is either of the incorrect length or contains a \x00 byte as the first character """ signer = keyczar.Signer.Read(os.path.join(TEST_DATA, "rsa-sign")) t = 0 flag = True while flag: t += 1 sig = util.Base64WSDecode(signer.Sign(t * "a")) assert (len(sig) == 256 + keyczar.HEADER_SIZE ) # 256 = keysize in bytes flag = sig[keyczar.HEADER_SIZE] != chr(0)
def Read(key): """ Reads a DSA private key from a JSON string representation of it. @param key: a JSON representation of a DSA private key @type key: string @return: an DSA private key @rtype: L{DsaPrivateKey} """ dsa = json.loads(key) pub = DsaPublicKey.Read(json.dumps(dsa['publicKey'])) params = { 'x' : util.Base64WSDecode(dsa['x']) } key = DSA.construct((util.BytesToLong(pub._params['y']), util.BytesToLong(pub._params['g']), util.BytesToLong(pub._params['p']), util.BytesToLong(pub._params['q']), util.BytesToLong(params['x']))) return DsaPrivateKey(params, pub, key, dsa['size'])
def Verify(self, data, sig): """ Verifies whether the signature corresponds to the given data. @param data: message that has been signed with sig @type data: string @param sig: Base64 string formatted as Header|Signature @type sig: string @return: True if sig corresponds to data, False otherwise. @rtype: boolean """ sig_bytes = util.Base64WSDecode(sig) if len(sig_bytes) < constants.HEADER_SIZE: raise errors.ShortSignatureError(len(sig_bytes)) return self.__InternalVerify(sig_bytes[:constants.HEADER_SIZE], sig_bytes[constants.HEADER_SIZE:], util.RawBytes(data))
class Key(object): """Parent class for Keyczar Keys.""" def __init__(self, key_type): self.type = key_type self.__size = self.type.default_size # initially default def __eq__(self, other): return (self.type == other.type and self.size == other.size and self.key_string == other.key_string) def __SetSize(self, new_size): if self.type.IsValidSize(new_size): self.__size = new_size def _GetKeyString(self): """Return the key as a string. Abstract method.""" def __GetKeyString(self): """Indirect getter for the key string.""" return self._GetKeyString() def _Hash(self): """Compute and return the hash_id id of this key. Can override default hash_id.""" fullhash = util.Hash(util.IntToBytes(len(self.key_bytes)), self.key_bytes) return util.Base64WSEncode(fullhash[:keyczar.KEY_HASH_SIZE]) def __Hash(self): """Indirect getter for hash_id.""" return self._Hash() hash_id = property(__Hash, doc="""The hash_id id of the key.""") size = property(lambda self: self.__size, __SetSize, doc="""The size of the key in bits.""") key_string = property(__GetKeyString, doc="""The key as a Base64 string.""") key_bytes = property(lambda self: util.Base64WSDecode(self.key_string), doc="""The key as bytes.""") def Header(self): """Return the 5-byte header string including version byte, 4-byte hash_id.""" return chr(keyczar.VERSION) + util.Base64WSDecode(self.hash_id)
def testBadAesCiphertextsStream(self): crypter = keyczar.Crypter.Read(os.path.join(TEST_DATA, "aes")) ciphertext = util.Base64WSDecode(crypter.Encrypt(self.input_data)) bad = util.Base64WSEncode(chr(0)) char = chr(ord(ciphertext[2]) ^ 44) ciphertext = util.Base64WSEncode(ciphertext[:2]+char+ciphertext[3:]) try: stream = StringIO.StringIO(bad) decryption_stream = crypter.CreateDecryptingStreamReader(stream) self.__readFromStream(decryption_stream) except errors.ShortCiphertextError: pass try: stream = StringIO.StringIO(ciphertext) decryption_stream = crypter.CreateDecryptingStreamReader(stream) self.__readFromStream(decryption_stream) except errors.KeyNotFoundError: pass
def testBadAesCiphertextsStream(self): crypter = keyczar.Crypter.Read(os.path.join(TEST_DATA, "aes")) ciphertext = util.Base64WSDecode(crypter.Encrypt(self.input_data)) bad = util.Base64WSEncode(b'0x00') char = bytes([bytearray(ciphertext)[2] ^ 44]) ciphertext = util.Base64WSEncode(ciphertext[:2] + char + ciphertext[3:]) try: stream = io.BytesIO(util.RawBytes(bad)) decryption_stream = crypter.CreateDecryptingStreamReader(stream) self.__readFromStream(decryption_stream) except errors.ShortCiphertextError: pass try: stream = io.BytesIO(util.RawBytes(ciphertext)) decryption_stream = crypter.CreateDecryptingStreamReader(stream) self.__readFromStream(decryption_stream) except errors.KeyNotFoundError: pass
def Header(self): """ Return the 5-byte header string including version byte, 4-byte hash_id. """ return (bytes(bytearray([constants.VERSION])) + util.Base64WSDecode(self.hash_id))
def __init__(self, crypter, session_material): material_bytes = util.Base64WSDecode(session_material) writer, getoutput = util.BytesWriter() reader = util.BytesReader(material_bytes) crypter.DecryptIO(reader, writer) self._session = _Session.LoadPackedKey(getoutput())
def __modifyByteString(self, string, offset): decoded = util.Base64WSDecode(string) modified_char = chr(ord(decoded[offset]) ^ 0xFF) return util.Base64WSEncode(decoded[:offset] + modified_char + decoded[offset + 1:])
def Header(self): """Return the 5-byte header string including version byte, 4-byte hash_id.""" return chr(keyczar.VERSION) + util.Base64WSDecode(self.hash_id)