o
    MiN                     @   s   d dl Z d dlZd dlZd dlZd dlmZmZmZ d dlm	Z	 d dl
Z
d dlZd dlZd dlZdddZ		dd
dZ		dddZdd Zdd Zdd Zdd ZdS )    N)Cipher
algorithmsmodes)default_backendHS256c                 C   s  |d||d}t j|dd}t|ddd}t| ddd}| d| }	|d}
|dkrHt|
|	dt	j
 }n+|d	krZt|
|	dt	j }n|d
krlt|
|	dt	j }ntd| t|dd}| d| d| }|S )a  
    Sign data using JWS with HMAC for BillDesk integration
    
    Args:
        payload_string (str): The data to sign (usually encrypted JWE)
        signing_key (str): BillDesk provided signing key
        key_id (str): BillDesk provided signing key ID
        client_id (str): BillDesk provided client ID
        algorithm (str): JWS algorithm (default: "HS256")
    
    Returns:
        str: JWS signed string
    JWT)algtypkidclientid,:
separatorsutf-8=.r   HS384HS512Unsupported algorithm: )jsondumpsbase64urlsafe_b64encodeencodedecoderstriphmacnewhashlibsha256digestsha384sha512
ValueError)payload_stringsigning_keykey_id	client_id	algorithm
jws_headerheader_json
header_b64payload_b64signing_inputsigning_key_bytes	signaturesignature_b64jws_signed_data r4   ?/var/www/html/Testing_prj/Navya-Bakers/orders/billdesk_utils.pysign_jws_billdesk
   s(   
r6   356DIRECT	123.0.0.1c                 C   sh   dt t  | td||	||
d|dddd}tj|dd	}t||||}t||||}|||fS )
a  
    Complete BillDesk payment flow: Create payload -> Encrypt with JWE -> Sign with JWS
    
    Args:
        merc_id (str): Merchant ID
        amount (str): Payment amount
        return_url (str): Return URL
        encryption_key (str): Encryption key
        enc_key_id (str): Encryption key ID
        enc_client_id (str): Encryption client ID
        signing_key (str): Signing key
        sign_key_id (str): Signing key ID
        sign_client_id (str): Signing client ID
        currency (str): Currency code (default: "356" for INR)
        itemcode (str): Item code (default: "DIRECT")
        user_ip (str): User's IP address
    
    Returns:
        tuple: (original_payload, encrypted_data, signed_data)
    TEST%Y-%m-%dT%H:%M:%S+05:30internetIMozilla/5.0 (Windows NT 10.0; WOW64; rv:51.0) Gecko/20100101 Firefox/51.0gapplication/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9init_channelip
user_agentaccept_headerorderidmercid
order_dateamountcurrencyruitemcodedevicer   r   )inttimestrftimer   r   encrypt_jwe_billdeskr6   )merc_idrH   
return_urlencryption_key
enc_key_idenc_client_idr'   sign_key_idsign_client_idrI   rK   user_ippayloadpayload_jsonencrypted_datasigned_datar4   r4   r5   !encrypt_and_sign_billdesk_payment@   s"   
r]   c	                 C   sP   dt t  | td||||d|dddd}	tj|	dd	}
t|
|||S )
a\  
    Create and encrypt a BillDesk payment payload
    
    Args:
        merc_id (str): Merchant ID provided by BillDesk
        amount (str): Payment amount
        return_url (str): Return URL after payment
        encryption_key (str): BillDesk provided encryption key
        key_id (str): BillDesk provided encryption key ID
        client_id (str): BillDesk provided client ID
        currency (str): Currency code (default: "356" for INR)
        itemcode (str): Item code (default: "DIRECT")
        user_ip (str): User's IP address
    
    Returns:
        str: JWE encrypted payment data
    r:   r;   r<   r=   r>   r?   rD   r   r   )rM   rN   rO   r   r   rP   )rQ   rH   rR   rS   r(   r)   rI   rK   rX   rY   rZ   r4   r4   r5   encrypt_billdesk_paymentv   s   r^   c              	   C   sB  | d}t|dk r|dd}nt|dkr|dd }dd||d}tj|dd	}t| ddd
}t	
d}tt|t|t d}	|	 }
| d}|
| |  d}|
||
  }|
j}d}t|dd
}t|dd
}t|dd
}| d| d| d| d| 	}|S )aq  
    Encrypt data using JWE with AES-256-GCM for BillDesk integration
    
    Args:
        response_string (str): The payload to encrypt
        encryption_key (str): BillDesk provided encryption key
        key_id (str): BillDesk provided encryption key ID
        client_id (str): BillDesk provided client ID
    
    Returns:
        str: JWE encrypted string
    r           NdirA256GCM)r   encr
   r   r   r   r      backendascii r   )r   lenljustr   r   r   r   r   r   osurandomr   r   AESr   GCMr   	encryptorauthenticate_additional_dataupdatefinalizetag)response_stringrS   r(   r)   key
jwe_headerr,   r-   ivcipherro   aadpayload_bytes
ciphertextauth_tagencrypted_keyiv_b64ciphertext_b64tag_b64jwe_encrypted_datar4   r4   r5   rP      s4   




 rP   c              
   C   s  z|  d}t|dkr@|\}}}|ddt|d  d   }z
t|d}W n( ty? } z	tdt| d }~ww t|dkrI| }n
tdt| d	| d}	t|	dkrgtd
t|	 |	\}
}}}}|
ddt|
d  d   }zt|d}t	|}W n ty } z	tdt| d }~ww |
ddkrtd|
d d|
ddkrtd|
d dz$|d}|drt|dd  }t|dkrtdt| W n ty } z	tdt| d }~ww dd }|r
tdz||}||}||}W n ty. } z	tdt| d }~ww t|dkr@tdt| dz(tt|t||t d}| }|
d }|| |||  }W n ty~ } z	td!t| d }~ww z|d}t	|}W n, tjy } z	td"t| d }~w ty } z	td#t| d }~ww t|tstd$| |W S    td!t| )%Nr      r      r   zFailed to decode JWS payload:    zInvalid format - got z# parts, expected 3 (JWS) or 5 (JWE)z,Invalid JWE format - must have 5 parts, got z&Failed to decode or parse JWE header: r   ra   r   z, expected 'dir'rc   rb   zUnsupported encryption method: z, expected 'A256GCM'zb64:r_   z%Encryption key must be 32 bytes, got zInvalid encryption key: c                 S   s&   | ddt | d  d   }t|S )Nr   r   )ri   r   urlsafe_b64decode)datapaddedr4   r4   r5   base64url_decode#  s   
z!decrypt.<locals>.base64url_decodez0Expected empty encrypted key for 'dir' algorithmz!Failed to decode JWE components: rd   zInvalid IV length: z, expected 12re   rg   Decryption failed: z Failed to parse decrypted JSON: z!Failed to decode decrypted data: z$Decrypted data is not a dictionary: )splitri   r   r   r   	Exceptionr%   strr   loadsgetr   
startswith	b64decoder   r   rm   r   rn   r   	decryptorrp   rq   rr   JSONDecodeError
isinstancedict)r[   rS   partsjws_header_b64jws_payload_b64jws_signature_b64jws_payload_paddedr   e	jwe_partsr-   encrypted_key_b64r~   r   r   header_b64_paddedr,   headerru   r   rw   r{   r|   rx   r   ry   decrypted_bytesdecrypted_stringdecrypted_jsonr4   r4   r5   decrypt   s   







r   c              
   C   s<   zt | |}|W S  ty } z	tdt| d}~ww )a  
    Decrypt JWE data using AES-256-GCM for BillDesk integration
    Handles both direct JWE and nested JWS->JWE formats
    
    Args:
        encrypted_data (str): The JWE encrypted string or JWS containing JWE
        encryption_key (str): BillDesk provided encryption key
    
    Returns:
        dict: Decrypted and parsed JSON payload with 'bdorderid' key
    
    Raises:
        ValueError: If decryption, JSON parsing, or structure validation fails
    r   N)r   r   r%   r   )r[   rS   r   r   r4   r4   r5   decrypt_jwe_billdeskO  s   
r   c              
   C   s&  |  d}tdt|  t|dkrtd |\}}}z'|ddt|d   d  }tt|d}tdtj|d	d
  W n   td Y zg|ddt|d   d  }t|d}td|  | d}	tdt|	  t|	dkrz+|	d ddt|	d d   d  }
tt|
d}tdtj|d	d
  W n   td Y W nX t	y } ztd|  W Y d}~nDd}~ww t|dkrtd z+|d ddt|d d   d  }tt|d}tdtj|d	d
  W n   td Y td dS )z?
    Analyze the structure of encrypted data from BillDesk
    r   zNumber of parts: r   z Format: JWS (JSON Web Signature)r   r   r   zJWS Header:    )indentzCould not decode JWS headerzJWS Payload (JWE): zJWE parts in payload: r   r   zJWE Header: zCould not decode JWE headerzCould not decode JWS payload: Nz!Format: JWE (JSON Web Encryption)z2--------------------------------------------------)
r   printri   r   r   r   r   r   r   r   )r[   r   r   r   r   jws_header_paddedr+   r   jws_payloadr   jwe_header_paddedrv   r   header_paddedr   r4   r4   r5   analyze_encrypted_datae  sL   



$
$
r   )r   )r7   r8   r9   )r   r   r   r    &cryptography.hazmat.primitives.ciphersr   r   r   cryptography.hazmat.backendsr   rk   rN   requestsuuidr6   r]   r^   rP   r   r   r   r4   r4   r4   r5   <module>   s"    
9
7
.Aj