def test_decode_dss_invalid_asn1(): with pytest.raises(ValueError): # This byte sequence has an invalid ASN.1 sequence length as well as # an invalid integer length for the second integer. decode_dss_signature(b"0\x07\x02\x01\x01\x02\x02\x01") with pytest.raises(ValueError): # This is the BER "end-of-contents octets". decode_dss_signature(b"\x00\x00")
def test_decode_dss_invalid_asn1(): with pytest.raises(ValueError): # This byte sequence has an invalid ASN.1 sequence length as well as # an invalid integer length for the second integer. decode_dss_signature(b"0\x07\x02\x01\x01\x02\x02\x01") with pytest.raises(ValueError): # This is the BER "end-of-contents octets," which older versions of # pyasn1 are wrongly willing to return from top-level DER decoding. decode_dss_signature(b"\x00\x00")
def der_to_raw_signature(der_sig, curve): num_bits = curve.key_size num_bytes = (num_bits + 7) // 8 r, s = decode_dss_signature(der_sig) return number_to_bytes(r, num_bytes) + number_to_bytes(s, num_bytes)
def der_to_raw_signature(der_sig: bytes, curve: EllipticCurve) -> bytes: num_bits = curve.key_size num_bytes = (num_bits + 7) // 8 r, s = decode_dss_signature(der_sig) return number_to_bytes(r, num_bytes) + number_to_bytes(s, num_bytes)
def test_cryptography_module(): try: from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives.asymmetric import dsa from cryptography.hazmat.primitives.asymmetric.utils import decode_dss_signature privk = dsa.generate_private_key(key_size=1024, backend=default_backend()) params = privk.parameters().parameter_numbers() p, q, g = params.p, params.q, params.g pubk = privk.public_key() y = pubk.public_numbers().y data = "SANITY_TESTSANITY_TEST_SANITYTEST" sig = privk.sign(data, hashes.SHA1()) r, s = decode_dss_signature(sig) pub = (p, q, g, y) logging.debug( "sanity checking verify with cryptography module generated params+keys" ) assert (dsa_verify(pub, (r, s), data) == True) except ImportError: logging.error("cannot test using another source (cryptography module)")
def sign(self, data): """ Sign some data with this key. SECSH-TRANS RFC 4253 Section 6.6. @type data: L{bytes} @param data: The data to sign. @rtype: L{bytes} @return: A signature for the given data. """ if self.type() == 'RSA': signer = self._keyObject.signer( padding.PKCS1v15(), hashes.SHA1()) signer.update(data) ret = common.NS(signer.finalize()) elif self.type() == 'DSA': signer = self._keyObject.signer(hashes.SHA1()) signer.update(data) signature = signer.finalize() (r, s) = decode_dss_signature(signature) # SSH insists that the DSS signature blob be two 160-bit integers # concatenated together. The sig[0], [1] numbers from obj.sign # are just numbers, and could be any length from 0 to 160 bits. # Make sure they are padded out to 160 bits (20 bytes each) ret = common.NS(int_to_bytes(r, 20) + int_to_bytes(s, 20)) else: raise BadKeyError("unknown key type %s" % (self.type(),)) return common.NS(self.sshType()) + ret
def _ecc_static_length_signature(key, algorithm, digest): """Calculates an elliptic curve signature with a static length using pre-calculated hash. :param key: Elliptic curve private key :type key: cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePrivateKey :param algorithm: Master algorithm to use :type algorithm: aws_encryption_sdk.identifiers.Algorithm :param bytes digest: Pre-calculated hash digest :returns: Signature with required length :rtype: bytes """ pre_hashed_algorithm = ec.ECDSA(Prehashed(algorithm.signing_hash_type())) signature = b'' while len(signature) != algorithm.signature_len: _LOGGER.debug( 'Signature length %d is not desired length %d. Recalculating.', len(signature), algorithm.signature_len) signature = key.sign(digest, pre_hashed_algorithm) if len(signature) != algorithm.signature_len: # Most of the time, a signature of the wrong length can be fixed # by negating s in the signature relative to the group order. _LOGGER.debug( 'Signature length %d is not desired length %d. Negating s.', len(signature), algorithm.signature_len) r, s = decode_dss_signature(signature) s = _ECC_CURVE_PARAMETERS[ algorithm.signing_algorithm_info.name].order - s signature = encode_dss_signature(r, s) return signature
def get_hnp_approximation(): global nsigs, count_true, count ud = os.urandom(8) res, ud, sig = sidechannel_cache(userdata=ud) nsigs += 1 m_b = compute_m_from_userdata(ud) m = int(m_b.encode("hex"), 16) r, s = decode_dss_signature(sig) q = order m = m % q flag = sidechannel_info.give_range(m, r, q) if res == 0: t, u, v = compute_approximation_from_sig(m, r, s, q, res) no_msb = math.log(q / v) / math.log(2) if no_msb > b: # print_flag(flag) # print_flag(res) # count+=1 # count_true+=int(flag==res) # print count,count_true,flag==res print flag == res return t, u, v else: return None else: return None
def _ecdsa_sha256_response(self, challenge): """Compute the ecdsa signature Args: challenge: content of challenge in bytes Returns: r_bytes, s_bytes: ecdsa signature R, S in bytes Raises: BootstrapError: if the gateway cannot be properly loaded """ try: challenge_key = cert_utils.load_key(self._challenge_key_file) except (IOError, ValueError, TypeError) as e: raise BootstrapError( 'Gateway does not have a proper challenge key: %s' % e) try: signature = challenge_key.sign(challenge, ec.ECDSA(hashes.SHA256())) except TypeError: raise BootstrapError( 'Challenge key cannot be used for ECDSA signature') r_int, s_int = decode_dss_signature(signature) r_bytes = r_int.to_bytes((r_int.bit_length() + 7) // 8, 'big') s_bytes = s_int.to_bytes((s_int.bit_length() + 7) // 8, 'big') return r_bytes, s_bytes
def sign(self, data): """ It will generate the signature for data on local private key """ return decode_dss_signature( self.private_key.sign( json.dumps(data).encode('utf-8'), ec.ECDSA(hashes.SHA256())))
def __msg2_sign(self, msg2, blob): priv_sig_key_bytes = bytes().fromhex( AttestationContext.common_ec_private_key_hex) priv_sig_key_int = int.from_bytes(priv_sig_key_bytes, byteorder='little', signed=False) common_ec_key = ec.derive_private_key(priv_sig_key_int, P_256, OPENSSL_BACKEND) sig_material = bytearray() sig_material += self.gb_x sig_material += self.gb_y sig_material += self.ga_x sig_material += self.ga_y # generate signature signature_der = common_ec_key.sign(bytes(sig_material), ec.ECDSA(SHA256())) r, s = decode_dss_signature(signature_der) sig_x = r.to_bytes(32, byteorder='little') sig_y = s.to_bytes(32, byteorder='little') # append to the binary blob to me CMACed blob += sig_x blob += sig_y # append to msg2 sig_sp = {} sig_sp['x_coord'] = base64.b64encode(sig_x).decode('utf-8') sig_sp['y_coord'] = base64.b64encode(sig_y).decode('utf-8') msg2['sig_sp'] = sig_sp
def sign(self, data): """ Sign some data with this key. SECSH-TRANS RFC 4253 Section 6.6. @type data: L{bytes} @param data: The data to sign. @rtype: L{bytes} @return: A signature for the given data. """ if self.type() == 'RSA': signer = self._keyObject.signer(padding.PKCS1v15(), hashes.SHA1()) signer.update(data) ret = common.NS(signer.finalize()) elif self.type() == 'DSA': signer = self._keyObject.signer(hashes.SHA1()) signer.update(data) signature = signer.finalize() (r, s) = decode_dss_signature(signature) # SSH insists that the DSS signature blob be two 160-bit integers # concatenated together. The sig[0], [1] numbers from obj.sign # are just numbers, and could be any length from 0 to 160 bits. # Make sure they are padded out to 160 bits (20 bytes each) ret = common.NS(int_to_bytes(r, 20) + int_to_bytes(s, 20)) else: raise BadKeyError("unknown key type %s" % (self.type(), )) return common.NS(self.sshType()) + ret
def sign(self, data): ''' generate a signature ''' return decode_dss_signature( self.private_key.sign( json.dumps(data).encode('utf-8'), ec.ECDSA(hashes.SHA256())))
def build_oca(): """ Builds a self-signed OCA certificate using ECSDA with SHA256 and curve NIST-P384. Returns a tuple of the private key and the signed certificate""" private_key = ec.generate_private_key( ec.SECP384R1, default_backend() ) public_nr = private_key.public_key().public_numbers() oca = bytearray(0x824) oca[0x0:0x4] = (1).to_bytes(4,'little') oca[0x4] = 0x00 # API Major oca[0x5] = 0x00 # API Minor oca[0x6:0x8] = b'\x00\x00' oca[0x8:0xc] = (0x1001).to_bytes(4,'little') # Usage: OCA oca[0xc:0x10] = (2).to_bytes(4,'little') # ECDSA-SHA256 # Begin pubkey oca[0x10:0x14] = (2).to_bytes(4,'little') # Curve ID: NIST-P384 oca[0x14:0x14+0x48] = (public_nr.x).to_bytes(0x48,'little') oca[0x5c:0x5c+0x48] = (public_nr.y).to_bytes(0x48,'little') # Begin signature oca[0x414:0x418] = (0x1001).to_bytes(4,'little') # 1st signature usage: OCA oca[0x418:0x41c] = (2).to_bytes(4,'little') # ECDSA-SHA256 sig = utils.decode_dss_signature(ecdsa_sign(private_key,oca[:0x414])) oca[0x41c:0x41c+0x48] = (sig[0]).to_bytes(0x48,'little') # R oca[0x464:0x464+0x48] = (sig[1]).to_bytes(0x48,'little') # S oca[0x61c:0x620] = (0x1000).to_bytes(4,'little') # 2nd signature usage: Invalid return (private_key, oca)
def build_pdh(pek): """ Builds the platform-diffie-hellman key (PDH) and signs it with the provided platform-endorsement-key (PEK). Returns a tuple of the signed PDH and the corresponding private key. """ private_key = ec.generate_private_key( ec.SECP384R1, default_backend() ) public_nr = private_key.public_key().public_numbers() pdh = bytearray(0x824) pdh[0x0:0x4] = (1).to_bytes(4,'little') pdh[0x4] = 0x0 # API Major pdh[0x5] = 0x00 # API Minor pdh[0x6:0x8] = b'\x00\x00' pdh[0x8:0xc] = (0x1003).to_bytes(4,'little') # Usage: PDH pdh[0xc:0x10] = (3).to_bytes(4,'little') # ECDH-SHA256 # Begin pubkey pdh[0x10:0x14] = (2).to_bytes(4,'little') # Curve ID: NIST-P384 pdh[0x14:0x14+0x48] = (public_nr.x).to_bytes(0x48,'little') pdh[0x5c:0x5c+0x48] = (public_nr.y).to_bytes(0x48,'little') # Begin 1st signature pdh[0x414:0x418] = (0x1002).to_bytes(4,'little') # 1st signature usage: PEK pdh[0x418:0x41c] = (2).to_bytes(4,'little') # ECDSA-SHA256 sig = utils.decode_dss_signature(ecdsa_sign(pek,pdh[:0x414])) # Sign with OCA pdh[0x41c:0x41c+0x48] = (sig[0]).to_bytes(0x48,'little') # R pdh[0x464:0x464+0x48] = (sig[1]).to_bytes(0x48,'little') # S # Begin 2nd signature pdh[0x61c:0x620] = (0x1000).to_bytes(4,'little') # 2nd signature usage: Invalid return (private_key, pdh)
def sign_ssh_data(self, data): key = dsa.DSAPrivateNumbers( x=self.x, public_numbers=dsa.DSAPublicNumbers( y=self.y, parameter_numbers=dsa.DSAParameterNumbers( p=self.p, q=self.q, g=self.g ) ) ).private_key(backend=default_backend()) signer = key.signer(hashes.SHA1()) signer.update(data) r, s = decode_dss_signature(signer.finalize()) m = Message() m.add_string('ssh-dss') # apparently, in rare cases, r or s may be shorter than 20 bytes! rstr = util.deflate_long(r, 0) sstr = util.deflate_long(s, 0) if len(rstr) < 20: rstr = zero_byte * (20 - len(rstr)) + rstr if len(sstr) < 20: sstr = zero_byte * (20 - len(sstr)) + sstr m.add_string(rstr + sstr) return m
def sign(self, message): message = _helpers.to_bytes(message) asn1_signature = self._key.sign(message, ec.ECDSA(hashes.SHA256())) # Convert ASN1 encoded signature to (r||s) raw signature. (r, s) = decode_dss_signature(asn1_signature) return utils.int_to_bytes(r, 32) + utils.int_to_bytes(s, 32)
def get_cose_es_bytes(options, private_key, sig_val): ASN1_signature = private_key.sign(sig_val, ec.ECDSA(hashes.SHA256())) r, s = asymmetric_utils.decode_dss_signature(ASN1_signature) ssize = private_key.key_size signature_bytes = r.to_bytes(ssize // 8, byteorder='big') + s.to_bytes( ssize // 8, byteorder='big') return signature_bytes
def createPrivateSignature(context): data = bytes(context, encoding='utf8') # Read the pri_key_file digest = hashes.Hash(hashes.SHA256(), default_backend()) digest.update(data) dgst = digest.finalize() skey = load_pem_private_key(PRIVATE_KEY, password=None, backend=default_backend()) sig_data = skey.sign(data, ec.ECDSA(hashes.SHA256())) sig_r, sig_s = decode_dss_signature(sig_data) sig_bytes = b'' key_size_in_bytes = bit_to_bytes(skey.public_key().key_size) sig_r_bytes = sig_r.to_bytes(key_size_in_bytes, "big") sig_bytes += sig_r_bytes #print("ECDSA signature R: {:s}".format(sig_r_bytes.hex())) sig_s_bytes = sig_s.to_bytes(key_size_in_bytes, "big") sig_bytes += sig_s_bytes # print("ECDSA signature S: {:s}".format(sig_s_bytes.hex())) # print("ECDSA signautre: {:s}".format(sig_bytes.hex())) #print("ECDSA signautre: " + str(base64.b64encode(sig_bytes))) return base64.b64encode(sig_bytes)
def create_key_signature(private_key: bytes, challenger_public_key: bytes, enclave_public_key: bytes): logging.info("Creating key signature") assert len(challenger_public_key) == 64 assert len(enclave_public_key) == 64 # Reverse public key byte order g_b = challenger_public_key[:32][::-1] + challenger_public_key[32:][::-1] g_a = enclave_public_key[:32][::-1] + enclave_public_key[32:][::-1] gb_ga = g_b + g_a logging.debug("gb_ga: %r | %r\n", g_b.hex(), g_a.hex()) private_value = int.from_bytes(private_key, byteorder='big') ec_private_key = ec.derive_private_key(private_value, EC_CURVE, default_backend()) der_signature = ec_private_key.sign(gb_ga, ec.ECDSA(hashes.SHA256())) r, s = utils.decode_dss_signature(der_signature) signature = r.to_bytes(32, byteorder='big') + s.to_bytes(32, byteorder='big') logging.debug("challenger_public_key (g_b): %r | %r\n", challenger_public_key[:32].hex(), challenger_public_key[32:].hex()) logging.debug("enclave_public_key (g_a): %r | %r\n", enclave_public_key[:32].hex(), enclave_public_key[32:].hex()) logging.debug("signature: %r | %r\n", signature[:32].hex(), signature[32:].hex()) assert len(signature) == 64 return signature
def sign(self, header, payload): """Computes the signed jws as defined at rfc7515#section-7.1. Args: header: bytes, the header to be signed. payload: bytes, the payload to be signed. Returns: base64url(header) || '.' || base64url(payload) || '.' || base64url(signature), where the signature is computed over base64url(utf8(header)) || '.' || base64url(payload). """ if not isinstance(header, six.binary_type) or not isinstance( payload, six.binary_type): raise TypeError("header and payload must be bytes.") signing_input = jwsutil.urlsafe_b64encode( header) + b"." + jwsutil.urlsafe_b64encode(payload) signature = self.signer.sign(signing_input) if self.algorithm[:2] == "ES": # Standard Ecdsa signature is the DER encoding of [r, s] while Jws's # singature is the concatenation of r and s. (r, s) = utils.decode_dss_signature(signature) curve_length = jwsutil.ecdsa_algorithm_to_curve_length( self.algorithm) signature = jwsutil.int_to_bytes( r, curve_length) + jwsutil.int_to_bytes(s, curve_length) return signing_input + b"." + jwsutil.urlsafe_b64encode(signature)
def signature(self, msg): """ Create a signature for a message in a backwards compatible fashion :param msg: the message to sign """ # Create the pyca signature signer = self.ec.signer(ec.ECDSA(hashes.SHA1())) signer.update(msg) signature = signer.finalize() # Decode the DSS r and s variables from the pyca signature # We are going to turn these longs into (binary) string format r, s = decode_dss_signature(signature) # Convert the r and s to a valid hex representation r = hex(r).rstrip("L").lstrip("0x") or "0" s = hex(s).rstrip("L").lstrip("0x") or "0" # We want bytes: one byte is two nibbles: # Prefix with a 0 if the result is of odd length if len(r) % 2 == 1: r = "0" + r if len(s) % 2 == 1: s = "0" + s # Now we can turn this into a binary string r = unhexlify(r) s = unhexlify(s) key_len = self.get_signature_length() / 2 # For easy decoding, prepend 0 to r and s until they are of >equal length< return "".join( ("\x00" * (key_len - len(r)), r, "\x00" * (key_len - len(s)), s))
def sign(self, data): """ Generate a signature based on the data using the local private key. """ return decode_dss_signature( self.private_key.sign( json.dumps(data).encode('utf-8'), ec.ECDSA(hashes.SHA256())))
def sign(self, key: ec.EllipticCurvePrivateKey, msg: bytes) -> bytes: """Sign the ``msg`` using ``key``.""" sig = self._sign(key, msg) dr, ds = decode_dss_signature(sig) length = jwk.JWKEC.expected_length_for_curve(key.curve) return (dr.to_bytes(length=length, byteorder='big') + ds.to_bytes(length=length, byteorder='big'))
def sign_prehashed(self, hash): sig_der = self.key.sign(hash, ec.ECDSA(utils.Prehashed(SHA256()))) signature = utils.decode_dss_signature(sig_der) signature_bin = signature[0].to_bytes(32, 'big') signature_bin += signature[1].to_bytes(32, 'big') return signature_bin
def ecc_sign(self, private_key: Union[ec.EllipticCurvePrivateKey, bytes], data: bytes, algorithm: str = None) -> bytes: """Sign data using (EC)DSA. :param private_key: ECC private key :param data: Data to sign :param algorithm: Hash algorithm, if None the hash length is determined from ECC curve size :return: Signature, r and s coordinates as bytes """ if isinstance(private_key, bytes): private_key = serialization.load_pem_private_key( private_key, None, default_backend()) assert isinstance(private_key, ec.EllipticCurvePrivateKey) hash_name = algorithm or f'sha{private_key.key_size}' der_signature = private_key.sign(data, signature_algorithm=ec.ECDSA( self._get_algorithm(hash_name))) # pylint: disable=invalid-name # we want to use established names r, s = utils.decode_dss_signature(der_signature) coordinate_size = math.ceil(private_key.key_size / 8) r_bytes = r.to_bytes(coordinate_size, byteorder='big') s_bytes = s.to_bytes(coordinate_size, byteorder='big') return r_bytes + s_bytes
def sign(self, header, payload): """Computes the signed jws as defined at rfc7515#section-7.1. Args: header: dict, dictionary of header to convert to JSON and sign. payload: dict, dictionary of the payload to conert to JSON and sign. Returns: bytes, the signed token as defined at https://tools.ietf.org/html/rfc7515#section-7.1. Raises: SecurityException: if the header's algorithm or kid does not match the key's. """ if ((header.get("alg", None) is not None and header["alg"] != self.algorithm) or (header.get("kid", None) is not None and getattr(self, "kid", None) is not None and header["kid"] != self.kid)): raise SecurityException( "Header's algorithm or kid does not match the key's") signing_input = jwsutil.urlsafe_b64encode( jwsutil.json_encode(header)) + b"." + jwsutil.urlsafe_b64encode( jwsutil.json_encode(payload)) signature = self.signer.sign(signing_input) if self.algorithm[:2] == "ES": # Standard Ecdsa signature is the DER encoding of [r, s] while Jws's # singature is the concatenation of r and s. (r, s) = utils.decode_dss_signature(signature) curve_length = jwsutil.ecdsa_algorithm_to_curve_length( self.algorithm) signature = jwsutil.int_to_bytes( r, curve_length) + jwsutil.int_to_bytes(s, curve_length) return signing_input + b"." + jwsutil.urlsafe_b64encode(signature)
def test_dss_signature(): sig = encode_dss_signature(1, 1) assert sig == b"0\x06\x02\x01\x01\x02\x01\x01" assert decode_dss_signature(sig) == (1, 1) r_s1 = (1037234182290683143945502320610861668562885151617, 559776156650501990899426031439030258256861634312) sig2 = encode_dss_signature(*r_s1) assert sig2 == ( b'0-\x02\x15\x00\xb5\xaf0xg\xfb\x8bT9\x00\x13\xccg\x02\r\xdf\x1f,\x0b' b'\x81\x02\x14b\r;"\xabP1D\x0c>5\xea\xb6\xf4\x81)\x8f\x9e\x9f\x08') assert decode_dss_signature(sig2) == r_s1 sig3 = encode_dss_signature(0, 0) assert sig3 == b"0\x06\x02\x01\x00\x02\x01\x00" assert decode_dss_signature(sig3) == (0, 0)
def convert_ecdsa_signature_from_der_to_p1363( signature_der: bytes, key_size_bits: int ) -> bytes: (r, s) = decode_dss_signature(signature_der) assert key_size_bits % 8 == 0 n = key_size_bits // 8 signature_p1363 = r.to_bytes(n, byteorder="big") + s.to_bytes(n, byteorder="big") return signature_p1363
def sign(self, message): message = _helpers.to_bytes(message) asn1_signature = self._key.sign(message, ec.ECDSA(hashes.SHA256())) # Convert ASN1 encoded signature to (r||s) raw signature. (r, s) = decode_dss_signature(asn1_signature) return r.to_bytes(32, byteorder="big") + s.to_bytes(32, byteorder="big")
def sign(self, data): ''' Generate a signature based on the data using the local private key. ''' return decode_dss_signature(self.private_key.sign( json.dumps(data).encode('utf-8'), ec.ECDSA(hashes.SHA256()) ))#DSA here is digital signature algorithm
def sign_ssh_data(self, data): ecdsa = ec.ECDSA(self.ecdsa_curve.hash_object()) sig = self.signing_key.sign(data, ecdsa) r, s = decode_dss_signature(sig) m = Message() m.add_string(self.ecdsa_curve.key_format_identifier) m.add_string(self._sigencode(r, s)) return m
def sign(self, data, hash_context): if not isinstance(hash_context, hashes.HashContext): raise TypeError("hash_context must be an instance of hashes.HashContext.") signer = self._key.signer(hashes.SHA256()) signer._hash_ctx = hash_context signer.update(data) r, s = decode_dss_signature(signer.finalize()) # return long_to_bytes(r, 20) + long_to_bytes(s, 20) size = self.private_numbers.public_numbers.parameter_numbers.q.bit_length() // 8 return long_to_bytes(r, size) + long_to_bytes(s, size)
def test_dss_signature(): sig = encode_dss_signature(1, 1) assert sig == b"0\x06\x02\x01\x01\x02\x01\x01" assert decode_dss_signature(sig) == (1, 1) r_s1 = (1037234182290683143945502320610861668562885151617, 559776156650501990899426031439030258256861634312) sig2 = encode_dss_signature(*r_s1) assert sig2 == ( b"0-\x02\x15\x00\xb5\xaf0xg\xfb\x8bT9\x00\x13\xccg\x02\r\xdf\x1f,\x0b" b'\x81\x02\x14b\r;"\xabP1D\x0c>5\xea\xb6\xf4\x81)\x8f\x9e\x9f\x08' ) assert decode_dss_signature(sig2) == r_s1 sig3 = encode_dss_signature(0, 0) assert sig3 == b"0\x06\x02\x01\x00\x02\x01\x00" assert decode_dss_signature(sig3) == (0, 0) sig4 = encode_dss_signature(-1, 0) assert sig4 == b"0\x06\x02\x01\xFF\x02\x01\x00" assert decode_dss_signature(sig4) == (-1, 0)
def sign(self, payload): """ Sign a payload :param payload: String (usually jwt payload) :return: URL safe base64 signature """ signer = self._private_key.signer(ec.ECDSA(hashes.SHA256())) signer.update(payload) signature = signer.finalize() r, s = decode_dss_signature(signature) b64_signature = utils.base64url_encode('{r}{s}'.format(r=int2bytes(r), s=int2bytes(s))) return b64_signature
def sign(self, payload): """ Sign a payload :param payload: String (usually jwt payload) :return: URL safe base64 signature """ signer = self._private_key.signer(ec.ECDSA(hashes.SHA256())) signer.update(utils.to_bytes(payload)) signature = signer.finalize() r, s = decode_dss_signature(signature) br = int2bytes(r, KEYSIZE_BYTES) bs = int2bytes(s, KEYSIZE_BYTES) str_sig = br + bs b64_signature = utils.base64url_encode(str_sig) return b64_signature
def sign(claims, key): """Sign the claims :param claims: list of JWS claims :type claims: dict :param key: Private key for signing :type key: ec.EllipticCurvePrivateKey :param algorithm: JWT "alg" descriptor :type algorithm: str """ header = b64urlencode(b"""{"typ":"JWT","alg":"ES256"}""") # Unfortunately, chrome seems to require the claims to be sorted. claims = b64urlencode(json.dumps(claims, separators=(',', ':'), sort_keys=True).encode('utf8')) token = "{}.{}".format(header, claims) rsig = key.sign(token.encode('utf8'), ec.ECDSA(hashes.SHA256())) (r, s) = utils.decode_dss_signature(rsig) sig = b64urlencode(num_to_bytes(r) + num_to_bytes(s)) return "{}.{}".format(token, sig)
def der_decode(signature_bin): """ This decodes a DER encoded signature so that it can be used with ecdsa. It uses the decode_dss_signature() function from cryptography. :param signature_bin: DER encoded signature :type signature_bin: bytes :return: raw signature :rtype: bytes """ try: r, s = decode_dss_signature(signature_bin) sig_bin_asn = binascii.unhexlify('{0:064x}{1:064x}'.format(r, s)) except ValueError as _e: raise Exception("The signature is not in supported DER format.") # we can only check for too long signatures since we prepend the hex-values # with '0' to reach 64 digits. This will prevent an error in case the one of # the values (r, s) is smaller than 32 bytes (first byte is '0' # in original value). if len(sig_bin_asn) != 64: raise Exception("The signature needs to be 64 bytes.") return sig_bin_asn
def _der_to_raw(self, der_signature): """Convert signature from DER encoding to RAW encoding.""" r, s = decode_dss_signature(der_signature) component_length = self._sig_component_length() return int_to_bytes(r, component_length) + int_to_bytes(s, component_length)
def test_decode_dss_trailing_bytes(): with pytest.raises(ValueError): decode_dss_signature(b"0\x06\x02\x01\x01\x02\x01\x01\x00\x00\x00")