def calcKCV(keyValue, zAES=False):
"""Calculate KCV for symmetric key.
keyValue - key values as string (DES, 3DES2k, 3DES3k, AES)
zAES - True if key is AES (i.e. encrypt block of '01' instead of '00')
Return 3B-long string."""
if zAES:
assert len(keyValue) in (16, 24, 32), "Wrong length of AES key"
block = '\x01'*16
tkey = AES.new(keyValue, AES.MODE_ECB)
else:
assert len(keyValue) in (8, 16, 24), "Wrong length of (3)DES key"
block = '\x00'*8
if len(keyValue) == 8:
tkey = DES.new(keyValue, DES.MODE_ECB)
else:
tkey = DES3.new(keyValue, DES.MODE_ECB)
return tkey.encrypt(block)[:3]
python类new()的实例源码
def selectApplet(c, AID, logCh=0):
""" Select applet on a given logical channel or
open new log. channel if logCh is None. """
if logCh is None:
logCh = openLogCh(c)
# select the Applet on the given logical channel
apdu = [logCh, INS_SELECT, 4, 0, len(AID)] + s2l(AID)
resp, sw1, sw2 = c.transmit(apdu)
if sw1 == 0x6C and len(AID) == 0:
apdu = [logCh, INS_SELECT, 4, 0, sw2]
resp, sw1, sw2 = c.transmit(apdu)
if(sw1 == 0x61):
apdu = [logCh, 0xC0, 0, 0, sw2]
resp, sw1, sw2 = c.transmit(apdu)
sw = (sw1 << 8) + sw2
if sw != 0x9000:
raise ISOException(sw)
respdata = l2s(resp)
# close channel
return (respdata, logCh)
def changePin(c, oldPin, newPin, P2=0x01, logCh=0):
"""Change PIN
oldPin - old PIN value (str, 4-8bytes)
newPin - new PIN value (str, 4-8bytes)
P2 - PIN identification (0x01: PIN1 (default), 0x81: PIN2, etc.)
logCh - logical channel (default 0)
"""
assert 4 <= len(oldPin) <= 8
oldPin += '\xFF' * (8 - len(oldPin))
assert 4 <= len(newPin) <= 8
newPin += '\xFF' * (8 - len(newPin))
apdu = [logCh, INS_CHANGE_PIN, 0, P2, 0x10] + s2l(oldPin) + s2l(newPin)
resp, sw1, sw2 = c.transmit(apdu)
sw = (sw1 << 8) + sw2
if sw != 0x9000:
raise ISOException(sw)
def sign(self, data):
"""
Sign data (as str) by KID key.
Return signature as str."""
if self.zAES:
data = [ord(x) for x in data]
sLB = len(data) % self.BS
if(sLB > 0 or len(data) == 0):
data += [0x80] + [0]*(self.BS-sLB-1)
xorkey = self.xorKey2
else:
xorkey = self.xorKey1
for i in xrange(self.BS):
data[-self.BS+i] ^= ord(xorkey[i])
cipher = AES.new(self.keyval, AES.MODE_CBC, IV='\0'*16)
data = ''.join([chr(x) for x in data])
sig = cipher.encrypt(data)[-self.BS:]
return sig[:self.TlenB]
else:
padlen = len(data) % self.BS
if padlen > 0:
padlen = self.BS - padlen
sig = self.cipher(data + '\0'*padlen, True)
return sig[-self.BS:]
def runTest(self):
from Crypto.Cipher import DES
from binascii import b2a_hex
X = []
X[0:] = [b('\x94\x74\xB8\xE8\xC7\x3B\xCA\x7D')]
for i in range(16):
c = DES.new(X[i],DES.MODE_ECB)
if not (i&1): # (num&1) returns 1 for odd numbers
X[i+1:] = [c.encrypt(X[i])] # even
else:
X[i+1:] = [c.decrypt(X[i])] # odd
self.assertEqual(b2a_hex(X[16]),
b2a_hex(b('\x1B\x1A\x2D\xDB\x4C\x64\x24\x38')))
def decrypt_secret(secret, key):
"""Python implementation of SystemFunction005.
Decrypts a block of data with DES using given key.
Note that key can be longer than 7 bytes."""
decrypted_data = ''
j = 0 # key index
for i in range(0, len(secret), 8):
enc_block = secret[i:i + 8]
block_key = key[j:j + 7]
des_key = hashdump.str_to_key(block_key)
des = DES.new(des_key, DES.MODE_ECB)
decrypted_data += des.decrypt(enc_block)
j += 7
if len(key[j:j + 7]) < 7:
j = len(key[j:j + 7])
(dec_data_len,) = struct.unpack("<L", decrypted_data[:4])
return decrypted_data[8:8 + dec_data_len]
def runTest(self):
from Crypto.Cipher import DES
from binascii import b2a_hex
X = []
X[0:] = [b('\x94\x74\xB8\xE8\xC7\x3B\xCA\x7D')]
for i in range(16):
c = DES.new(X[i],DES.MODE_ECB)
if not (i&1): # (num&1) returns 1 for odd numbers
X[i+1:] = [c.encrypt(X[i])] # even
else:
X[i+1:] = [c.decrypt(X[i])] # odd
self.assertEqual(b2a_hex(X[16]),
b2a_hex(b('\x1B\x1A\x2D\xDB\x4C\x64\x24\x38')))
def decrypt(cls, key, keyusage, ciphertext):
if len(ciphertext) < 24:
raise ValueError('ciphertext too short')
cksum, basic_ctext = ciphertext[:16], ciphertext[16:]
ki = HMAC.new(key.contents, cls.usage_str(keyusage), MD5).digest()
ke = HMAC.new(ki, cksum, MD5).digest()
basic_plaintext = ARC4.new(ke).decrypt(basic_ctext)
exp_cksum = HMAC.new(ki, basic_plaintext, MD5).digest()
ok = _mac_equal(cksum, exp_cksum)
if not ok and keyusage == 9:
# Try again with usage 8, due to RFC 4757 errata.
ki = HMAC.new(key.contents, pack('<I', 8), MD5).digest()
exp_cksum = HMAC.new(ki, basic_plaintext, MD5).digest()
ok = _mac_equal(cksum, exp_cksum)
if not ok:
raise InvalidChecksum('ciphertext integrity failure')
# Discard the confounder.
return basic_plaintext[8:]
def ComputeSessionKeyStrongKey(sharedSecret, clientChallenge, serverChallenge, sharedSecretHash = None):
# added the ability to receive hashes already
if sharedSecretHash is None:
M4SS = ntlm.NTOWFv1(sharedSecret)
else:
M4SS = sharedSecretHash
md5 = hashlib.new('md5')
md5.update('\x00'*4)
md5.update(clientChallenge)
md5.update(serverChallenge)
finalMD5 = md5.digest()
hm = hmac.new(M4SS)
hm.update(finalMD5)
return hm.digest()
def DecryptAttributeValue(dce, attribute):
sessionKey = dce.get_session_key()
# Is it a Kerberos Session Key?
if isinstance(sessionKey, crypto.Key):
# Extract its contents and move on
sessionKey = sessionKey.contents
encryptedPayload = ENCRYPTED_PAYLOAD(attribute)
md5 = hashlib.new('md5')
md5.update(sessionKey)
md5.update(encryptedPayload['Salt'])
finalMD5 = md5.digest()
cipher = ARC4.new(finalMD5)
plainText = cipher.decrypt(attribute[16:])
#chkSum = (binascii.crc32(plainText[4:])) & 0xffffffff
#if unpack('<L',plainText[:4])[0] != chkSum:
# print "RECEIVED 0x%x" % unpack('<L',plainText[:4])[0]
# print "CALCULATED 0x%x" % chkSum
return plainText[4:]
# 5.16.4 ATTRTYP-to-OID Conversion
def __decryptSecret(self, key, value):
# [MS-LSAD] Section 5.1.2
plainText = ''
encryptedSecretSize = unpack('<I', value[:4])[0]
value = value[len(value)-encryptedSecretSize:]
key0 = key
for i in range(0, len(value), 8):
cipherText = value[:8]
tmpStrKey = key0[:7]
tmpKey = self.__cryptoCommon.transformKey(tmpStrKey)
Crypt1 = DES.new(tmpKey, DES.MODE_ECB)
plainText += Crypt1.decrypt(cipherText)
key0 = key0[7:]
value = value[8:]
# AdvanceKey
if len(key0) < 7:
key0 = key[len(key0):]
secret = LSA_SECRET_XP(plainText)
return secret['Secret']
def __decryptLSA(self, value):
if self.__vistaStyle is True:
# ToDo: There could be more than one LSA Keys
record = LSA_SECRET(value)
tmpKey = self.__sha256(self.__bootKey, record['EncryptedData'][:32])
plainText = self.__cryptoCommon.decryptAES(tmpKey, record['EncryptedData'][32:])
record = LSA_SECRET_BLOB(plainText)
self.__LSAKey = record['Secret'][52:][:32]
else:
md5 = hashlib.new('md5')
md5.update(self.__bootKey)
for i in range(1000):
md5.update(value[60:76])
tmpKey = md5.digest()
rc4 = ARC4.new(tmpKey)
plainText = rc4.decrypt(value[12:60])
self.__LSAKey = plainText[0x10:0x20]
def computeResponseNTLMv1(flags, serverChallenge, clientChallenge, serverName, domain, user, password, lmhash='',
nthash='', use_ntlmv2=USE_NTLMv2):
if user == '' and password == '':
# Special case for anonymous authentication
lmResponse = ''
ntResponse = ''
else:
lmhash = LMOWFv1(password, lmhash, nthash)
nthash = NTOWFv1(password, lmhash, nthash)
if flags & NTLMSSP_NEGOTIATE_LM_KEY:
ntResponse = ''
lmResponse = get_ntlmv1_response(lmhash, serverChallenge)
elif flags & NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY:
md5 = hashlib.new('md5')
chall = (serverChallenge + clientChallenge)
md5.update(chall)
ntResponse = ntlmssp_DES_encrypt(nthash, md5.digest()[:8])
lmResponse = clientChallenge + '\x00'*16
else:
ntResponse = get_ntlmv1_response(nthash,serverChallenge)
lmResponse = get_ntlmv1_response(lmhash, serverChallenge)
sessionBaseKey = generateSessionKeyV1(password, lmhash, nthash)
return ntResponse, lmResponse, sessionBaseKey
def SEALKEY(flags, randomSessionKey, mode = 'Client'):
if flags & NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY:
if flags & NTLMSSP_NEGOTIATE_128:
sealKey = randomSessionKey
elif flags & NTLMSSP_NEGOTIATE_56:
sealKey = randomSessionKey[:7]
else:
sealKey = randomSessionKey[:5]
if mode == 'Client':
md5 = hashlib.new('md5')
md5.update(sealKey + 'session key to client-to-server sealing key magic constant\x00')
sealKey = md5.digest()
else:
md5 = hashlib.new('md5')
md5.update(sealKey + 'session key to server-to-client sealing key magic constant\x00')
sealKey = md5.digest()
elif flags & NTLMSSP_NEGOTIATE_56:
sealKey = randomSessionKey[:7] + '\xa0'
else:
sealKey = randomSessionKey[:5] + '\xe5\x38\xb0'
return sealKey
def decryptSecret(key, value):
# [MS-LSAD] Section 5.1.2
plainText = ''
key0 = key
for i in range(0, len(value), 8):
cipherText = value[:8]
tmpStrKey = key0[:7]
tmpKey = transformKey(tmpStrKey)
Crypt1 = DES.new(tmpKey, DES.MODE_ECB)
plainText += Crypt1.decrypt(cipherText)
cipherText = cipherText[8:]
key0 = key0[7:]
value = value[8:]
# AdvanceKey
if len(key0) < 7:
key0 = key[len(key0):]
secret = LSA_SECRET_XP(plainText)
return (secret['Secret'])
def encryptSecret(key, value):
# [MS-LSAD] Section 5.1.2
plainText = ''
cipherText = ''
key0 = key
value0 = pack('<LL', len(value), 1) + value
for i in range(0, len(value0), 8):
if len(value0) < 8:
value0 = value0 + '\x00'*(8-len(value0))
plainText = value0[:8]
tmpStrKey = key0[:7]
tmpKey = transformKey(tmpStrKey)
Crypt1 = DES.new(tmpKey, DES.MODE_ECB)
cipherText += Crypt1.encrypt(plainText)
plainText = plainText[8:]
key0 = key0[7:]
value0 = value0[8:]
# AdvanceKey
if len(key0) < 7:
key0 = key[len(key0):]
return cipherText
def SamDecryptNTLMHash(encryptedHash, key):
# [MS-SAMR] Section 2.2.11.1.1
Block1 = encryptedHash[:8]
Block2 = encryptedHash[8:]
Key1 = key[:7]
Key1 = transformKey(Key1)
Key2 = key[7:14]
Key2 = transformKey(Key2)
Crypt1 = DES.new(Key1, DES.MODE_ECB)
Crypt2 = DES.new(Key2, DES.MODE_ECB)
plain1 = Crypt1.decrypt(Block1)
plain2 = Crypt2.decrypt(Block2)
return plain1 + plain2
def SamEncryptNTLMHash(encryptedHash, key):
# [MS-SAMR] Section 2.2.11.1.1
Block1 = encryptedHash[:8]
Block2 = encryptedHash[8:]
Key1 = key[:7]
Key1 = transformKey(Key1)
Key2 = key[7:14]
Key2 = transformKey(Key2)
Crypt1 = DES.new(Key1, DES.MODE_ECB)
Crypt2 = DES.new(Key2, DES.MODE_ECB)
plain1 = Crypt1.encrypt(Block1)
plain2 = Crypt2.encrypt(Block2)
return plain1 + plain2
def runTest(self):
from Crypto.Cipher import DES
from binascii import b2a_hex
X = []
X[0:] = [b('\x94\x74\xB8\xE8\xC7\x3B\xCA\x7D')]
for i in range(16):
c = DES.new(X[i],DES.MODE_ECB)
if not (i&1): # (num&1) returns 1 for odd numbers
X[i+1:] = [c.encrypt(X[i])] # even
else:
X[i+1:] = [c.decrypt(X[i])] # odd
self.assertEqual(b2a_hex(X[16]),
b2a_hex(b('\x1B\x1A\x2D\xDB\x4C\x64\x24\x38')))