Created
September 30, 2022 05:43
-
-
Save Porush/b887c48b569cb988ebf5a03da0dfdbd5 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| public static function uidai_validate($uidai, $passcode) | |
| { | |
| $result = array( | |
| 'success' => false, | |
| 'error' => '', | |
| 'uidai' => '', | |
| 'img' => '', | |
| 'first_name' => '', | |
| 'last_name' => '', | |
| 'birth_date' => '', | |
| 'gender' => '', | |
| 'state' => '', | |
| 'city' => '', | |
| 'address' => '' | |
| ); | |
| $xml_file = null; | |
| $zip_file = new ZipArchive(); | |
| $zip_file_path = Storage::disk('data')->path('aadhaar_zip/' . $uidai . '.zip'); | |
| $zip_file_status = $zip_file->open($zip_file_path); | |
| if ($zip_file_status === true) { | |
| $zip_file->setPassword($passcode); | |
| if ($zip_file->extractTo(Storage::disk('data')->path('aadhaar_xml'))) { | |
| if (!str_ends_with($zip_file->getNameIndex(0), '.xml')) { | |
| $result['error'] = 3; | |
| return $result; | |
| } | |
| $xml_file = Storage::disk('data')->get('aadhaar_xml/' . $zip_file->getNameIndex(0)); | |
| } else { | |
| $result['error'] = 2; // Invalid passcode | |
| } | |
| $zip_file->close(); | |
| unlink($zip_file_path); | |
| } else { | |
| $result['error'] = 1; // Unable to open file | |
| } | |
| if ($xml_file) { | |
| $key_file = Storage::get("files/uidai_auth_sign_prod_2023.cer"); | |
| $key_file = openssl_x509_read($key_file); | |
| $xmlDoc = new DOMDocument(); | |
| $xmlDoc->loadXML($xml_file); | |
| $xml_data = simplexml_load_string($xml_file, null, LIBXML_NOBLANKS) or dd("Failed to load"); | |
| $xml_array = self::xml2array($xml_data); | |
| $reference_id = $xml_array['@attributes']['referenceId']; | |
| $aadhar_id = substr($reference_id, 0, 4); | |
| $time_stamp = substr($reference_id, 4); | |
| $photo = $xml_array['UidData']['Pht']; | |
| $dob = $xml_array['UidData']['Poi']['@attributes']['dob']; | |
| $email_hashed = $xml_array['UidData']['Poi']['@attributes']['e']; | |
| $gender = $xml_array['UidData']['Poi']['@attributes']['gender']; | |
| $mobile_hashed = $xml_array['UidData']['Poi']['@attributes']['m']; | |
| $name = $xml_array['UidData']['Poi']['@attributes']['name']; | |
| $country = $xml_array['UidData']['Poa']['@attributes']['country']; | |
| $district = $xml_array['UidData']['Poa']['@attributes']['dist']; | |
| $address = $xml_array['UidData']['Poa']['@attributes']['house']; | |
| $landmark = $xml_array['UidData']['Poa']['@attributes']['landmark']; | |
| $loc = $xml_array['UidData']['Poa']['@attributes']['loc']; | |
| $pincode = $xml_array['UidData']['Poa']['@attributes']['pc']; | |
| $postoffice = $xml_array['UidData']['Poa']['@attributes']['po']; | |
| $state = $xml_array['UidData']['Poa']['@attributes']['state']; | |
| $street = $xml_array['UidData']['Poa']['@attributes']['street']; | |
| $subdistrict = $xml_array['UidData']['Poa']['@attributes']['subdist']; | |
| $vtc = $xml_array['UidData']['Poa']['@attributes']['vtc']; | |
| $from = new DateTime(date('Y-m-d', strtotime($dob))); | |
| $to = new DateTime('today'); | |
| $age = $from->diff($to)->y; | |
| $hash_count = substr($aadhar_id, -1); //8 | |
| if ($hash_count == 0) { | |
| $hash_count = 1; | |
| } | |
| // Getting SignatureValue from XML | |
| $signature = $xml_array['Signature']['SignatureValue']; | |
| $signed_info = $xmlDoc->getElementsByTagName('SignedInfo')[0]; | |
| $signed_info = $signed_info->C14N(); | |
| $signed_info = hash('sha1', $signed_info); | |
| // Getting DigestValue from XML | |
| $digest = $xml_array['Signature']['SignedInfo']['Reference']['DigestValue']; | |
| $digest = bin2hex(base64_decode($digest)); | |
| // Removing Signature Part from XML | |
| $xml_child = $xml_data->xpath("/OfflinePaperlessKyc"); | |
| $xml_child = get_object_vars($xml_child[0]); | |
| $xml_child = $xml_child['Signature']; | |
| unset($xml_child[0]); | |
| $xml_without_signature = strval($xml_data->asXML()); | |
| $xmlDoc->loadXML($xml_without_signature);; | |
| $data = $xmlDoc->C14N(); | |
| $digest_test = hash('sha256', $data); | |
| //XML Data is Verified by DigestValue | |
| if ($digest == $digest_test) { | |
| $pub_key = openssl_pkey_get_public($key_file); | |
| $details = openssl_pkey_get_details($pub_key); | |
| $array = openssl_pkey_get_details($pub_key); | |
| $hex = array_map("bin2hex", $array["rsa"]); | |
| //For decryption we would use: | |
| $decrypted = ''; | |
| //decode must be done before spliting for getting the binary String | |
| $test_data = str_split(base64_decode($signature), 256); | |
| foreach ($test_data as $chunk) { | |
| $partial = ''; | |
| //be sure to match padding | |
| $decryptionOK = openssl_public_decrypt($chunk, $partial, $details['key'], OPENSSL_PKCS1_PADDING); | |
| if ($decryptionOK === false) { | |
| //return false; | |
| dd(openssl_error_string()); | |
| continue; | |
| } //here also processed errors in decryption. If too big this will be false | |
| $decrypted .= $partial; | |
| } | |
| $decrypted = bin2hex($decrypted); | |
| $start = strlen($decrypted) - 40; | |
| // substr returns the new string. | |
| $decrypted = substr($decrypted, $start); | |
| //XML Data is Verified by SignatureValue | |
| if ($signed_info == $decrypted) { | |
| $result['success'] = true; | |
| $result['uidai'] = $aadhar_id; | |
| $result['img'] = $photo; | |
| $result['first_name'] = strtolower(self::split_name($name)[0]); | |
| $result['last_name'] = strtolower(self::split_name($name)[1]); | |
| $birth_date = explode('-', $dob); | |
| $result['birth_date'] = $birth_date[2] . '-' . $birth_date[1] . '-' . $birth_date[0]; | |
| if (strtolower($gender) === 'm') { | |
| $result['gender'] = 'male'; | |
| } else { | |
| $result['gender'] = 'female'; | |
| } | |
| $result['state'] = strtolower($state); | |
| $result['city'] = strtolower($district); | |
| $result['address'] = strtolower($address . ', ' . $street . ', ' . $loc); | |
| } else { | |
| $result['error'] = 5; // Invalid signature | |
| } | |
| openssl_free_key($pub_key); | |
| } else { | |
| $result['error'] = 4; // Invalid digest | |
| } | |
| } | |
| return $result; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment