Python) Convert Big Endian to Little Endian
Using a bytearray (Try it online!):
data = "F324658951425AF3EB0011"
bits = [16, 8, 8, 32, 8, 16]
b = bytearray.fromhex(data)
i = 0
for n in bits:
n //= 8
b[i:i+n] = reversed(b[i:i+n])
i += n
print(b.hex().upper())
Or with memoryview (Try it online!):
data = "F324658951425AF3EB0011"
bits = [16, 8, 8, 32, 8, 16]
b = bytearray.fromhex(data)
m = memoryview(b)
for n in bits:
n //= 8
m[:n] = m[n-1::-1]
m = m[n:]
print(b.hex().upper())
Convert little endian string to integer
The struct
module converts packed data to Python values, and vice-versa.
>>> import struct
>>> struct.unpack("<h", "\x00\x05")
(1280,)
>>> struct.unpack("<h", "\x00\x06")
(1536,)
>>> struct.unpack("<h", "\x01\x06")
(1537,)
"h" means a short int, or 16-bit int. "<" means use little-endian.
Convert hex to uint16 little-endian
You need to process each element of the list separately, not the whole list at once. You can do this with a list comprehension.
If you want little-endian, you have to swap the halves of the string before parsing it as an integer:
hex = ['1A05','1A05','1A05']
endian = [int(h[2:4] + h[0:2], 16) for h in hex]
However, that will only work if the hex strings are always 4 characters. You can also swap the bytes of the integer using bit operations after parsing:
for h in hex:
i = int(h, 16)
i = i & 0xff << 16 | i & 0xff00 >> 16
endian.append(i)
changing the hash digest to big-endian in Python
As mentioned in my comment, I'm not sure if it is really required to invert the hash.
But if so, you need an implementation that does not process the raw data, but the already hashed data (and does not hash anymore).
PyCryptodome does not support this, but the Cryptography library with the Prehashed
class does, s. here, 2nd snippet.
The following code performs a signing with PKCS#1 v1.5 and:
- with PyCryptodome (implicit hashing)
- with Cryptography (implicit hashing)
- with Cryptography (using the Prehashed class and explicit hashing)
- with Cryptography (using the Prehashed class and explicit hashing) and using the inverted hash
# Short key only for testing purposes!
pkcs8 = '''-----BEGIN PRIVATE KEY-----
MIIBVQIBADANBgkqhkiG9w0BAQEFAASCAT8wggE7AgEAAkEA2gdsVIRmg5IH0rG3
u3w+gHCZq5o4OMQIeomC1NTeHgxbkrfznv7TgWVzrHpr3HHK8IpLlG04/aBo6U5W
2umHQQIDAQABAkEAu7wulGvZFat1Xv+19BMcgl3yhCdsB70Mi+7CH98XTwjACk4T
+IYv4N53j16gce7U5fJxmGkdq83+xAyeyw8U0QIhAPIMhbtXlRS7XpkB66l5DvN1
XrKRWeB3RtvcUSf30RyFAiEA5ph7eWXbXWpIhdWMoe50yffF7pW+C5z07tzAIH6D
Ko0CIQCyveSTr917bdIxk2V/xNHxnx7LJuMEC5DcExorNanKMQIgUxHRQU1hNgjI
sXXZoKgfaHaa1jUZbmOPlNDvYYVRyS0CIB9ZZee2zubyRla4qN8PQxCJb7DiICmH
7nWP7CIvcQwB
-----END PRIVATE KEY-----'''
message = b'The quick brown fox jumps over the lazy dog'
# 1. PyCryptodome (implicit hashing)
from Crypto.Signature import pkcs1_15
from Crypto.Hash import SHA256
from Crypto.PublicKey import RSA
privateKey = RSA.import_key(pkcs8)
digest = SHA256.new(message)
signature = pkcs1_15.new(privateKey).sign(digest)
print(signature.hex())
# 2. Cryptography (implicit hashing)
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.hazmat.primitives import serialization
privateKey = serialization.load_pem_private_key(
pkcs8.encode('utf8'),
password=None,
)
digest = hashes.SHA256()
signature = privateKey.sign(
message,
padding.PKCS1v15(),
digest
)
print(signature.hex())
# 3. Cryptography (explicit hashing)
from cryptography.hazmat.primitives.asymmetric import utils
digest = hashes.SHA256()
hasher = hashes.Hash(digest)
hasher.update(message)
hash = hasher.finalize()
signature = privateKey.sign(
hash,
padding.PKCS1v15(),
utils.Prehashed(digest) # The digest must still be specified because the digest ID is included in the signature.
)
print(signature.hex())
# 4. Cryptography (explicit hashing), inverse hash
hashBA = bytearray(hash)
hashBA.reverse()
hashReversed = bytes(hashBA)
signature = privateKey.sign(
hashReversed,
padding.PKCS1v15(),
utils.Prehashed(digest) # The digest must still be specified because the digest ID is included in the signature.
)
print(signature.hex())
with the output:
8c83cad897eda249fec9eba231061d585dafc99177267e3e71bb8a3fce07cc6663bf4df7af2e1c1945d2a6bb42eb25f042228b591fc18cda82d92caae844670c
8c83cad897eda249fec9eba231061d585dafc99177267e3e71bb8a3fce07cc6663bf4df7af2e1c1945d2a6bb42eb25f042228b591fc18cda82d92caae844670c
8c83cad897eda249fec9eba231061d585dafc99177267e3e71bb8a3fce07cc6663bf4df7af2e1c1945d2a6bb42eb25f042228b591fc18cda82d92caae844670c
550ba1cd3c968fa1e24b79a939edb6740b63d2ab021fe87f0639ce978d5127792661e83f4e8fdff8124a12fe208bd70bdca9db2b9c82306f2ed018ab06363c9e
Since the PKCS#1 v1.5 signature is deterministic, cases 1 to 3 produce the same signature.
Related Topics
Retrieving Subfolders Names in S3 Bucket from Boto3
Finding Non-Numeric Rows in Dataframe in Pandas
Pandas - How to Compare 2 CSV Files and Output Changes
Calculate Monthly Returns from Daily Returns in Pandas(Cumpound)
Swapping Columns in a Numpy Array
How to Block Comment Code in the Ipython Notebook
How to Print Superscript in Python
Python Pandas Count the Number of Occurances Inside Lists in a Column
How to Delete a Column That Contains Only Zeros in Pandas
How to Convert List into String With Quotes in Python
Type Conversion in Python Attributeerror: 'Str' Object Has No Attribute 'Astype'
Printing Even Characters With Strings in Python
Python How to Remove Escape Characters from a String
Plotting Data from Multiple Pandas Data Frames in One Plot
Python: How to Match Nested Parentheses With Regex