aadhaar-validator icon indicating copy to clipboard operation
aadhaar-validator copied to clipboard

Add Offline QR validator

Open srikanthlogic opened this issue 5 years ago • 11 comments

Utility functions for performing validation functions to validate Offline QR.

Reference - Archive

Download certificates for signature validation from UIDAI downloads page

Sample Unit Test Data for the given QR string in the reference

Content Length is : 1100 Data bytes is :185 Mobile Email Flag is 2 RefId is 890820190305150137123 Last 4 Digit of Aadhaar is 8908 Name is PENUMARTHI VENKAT DOB is 07-05-1987 Gender is M Address Care of is S/O: PATTABHI RAMA RAO Address District is EAST GODAVARI Address House is 4-83 Address location is SCTOR-2 Address PINCode is 533016 Address Post Office is ARATLAKATTA Address State is ANDHRA PRADESH Address Street is MAIN ROAD Address SubDistrict is KARAPA Address VTC is ARATLAKATTA Data End is 184 Email Hash is null Mobile Hash is 1F31F19AFC2BACBD8AFB84526AE4DA184A2727E8C2B1B6B9A81E4DC6B74D692A Photo Exists : true Signature Verify Data call is false

srikanthlogic avatar Jul 10 '19 03:07 srikanthlogic

@dinsaw Can I pick this task up?

anmol5varma avatar Aug 17 '19 18:08 anmol5varma

Note : The doc is conflicting on the value of Mobile/Email Flag in 2 different places, The below description in 3.1 section is correct and the other reference later on in the doc is incorrect.

0, 1, 2, 3: 0 -no mobile/email. 1-Only email. 2-Only mobile.3 -Both email/mobile

srikanthlogic avatar Aug 20 '19 13:08 srikanthlogic

Additional Test case from UIDAI Website - Archive

//Sumit Kumar With Photo, Email, Phone "2374971804270526477833002468783965837992554564899874087591661303561346432389832047870524302186901344489362368642972767716416349990805756094923115719687656090691368051627957878187788907419297818953295185555346288172578594637886352753543271000481717080003254556962148594350559820352806251787713278744047402230989238559317351232114240089849934148895256488140236015024800731753594740948640957680138566468247224859669467819596919398964809164399637893729212452791889199675715949918925838319591794702333094022248132120531152523331442741730158840977243402215102904932650832502847295644794421419704633765033761284508863534321317394686768650111457751139630853448637215423705157211510636160227953566227527799608082928846103264491539001327407775670834868948113753614112563650255058316849200536533335903554984254814901522086937767458409075617572843449110393213525925388131214952874629655799772119820372255291052673056372346072235458198199995637720424196884145247220163810790179386390283738429482893152518286247124911446073389185062482901364671389605727763080854673156754021728522287806275420847159574631844674460263574901590412679291518508010087116598357407343835408554094619585212373168435612645646129147973594416508676872819776522537778717985070402222824965034768103900739105784663244748432502180989441389718131079445941981681118258324511923246198334046020123727749408128519721102477302359413240175102907322619462289965085963377744024233678337951462006962521823224880199210318367946130004264196899778609815012001799773327514133268825910089483612283510244566484854597156100473055413090101948456959122378865704840756793122956663218517626099291311352417342899623681483097817511136427210593032393600010728324905512596767095096153856032112835755780472808814199620390836980020899858288860556611564167406292139646289142056168261133256777093245980048335918156712295254776487472431445495668303900536289283098315798552328294391152828182614909451410115516297083658174657554955228963550255866282688308751041517464999930825273776417639569977754844191402927594739069037851707477839207593911886893016618794870530622356073909077832279869798641545167528509966656120623184120128052588408742941658045827255866966100249857968956536613250770326334844204927432961924987891433020671754710428050564671868464658436926086493709176888821257183419013229795869757265111599482263223604228286513011751601176504567030118257385997460972803240338899836840030438830725520798480181575861397469056536579877274090338750406459700907704031830137890544492015701251066934352867527112361743047684237105216779177819594030160887368311805926405114938744235859610328064947158936962470654636736991567663705830950312548447653861922078087824048793236971354828540758657075837209006713701763902429652486225300535997260665898927924843608750347193892239342462507130025307878412116604096773706728162016134101751551184021079984480254041743057914746472840768175369369852937574401874295943063507273467384747124843744395375119899278823903202010381949145094804675442110869084589592876721655764753871572233276245590041302887094585204427900634246823674277680009401177473636685542700515621164233992970974893989913447733956146698563285998205950467321954304"

Mobile Email Flag is 3 RefId is 269720190308114407437 Last 4 Digit of Aadhaar is 2697 Name is SUMIT KUMAR DOB is 01-01-1984 Gender is M Address Care of is C/O ISHWAR CHAND Address District is EAST DELHI Address House is B-31, 3RD FLOOR Address location is Address PINCode is 110051 Address Post Office is KRISHNA NAGAR Address State is DELHI Address Street is RADHEY SHYAM PARK EXTENSION Address SubDistrict is GANDHI NAGAR Address VTC is KRISHNA NAGAR Data End is 176 Email Hash is EB5998353B21BAC1381D750E1FA26641E096AF391D115FADADD47BF4FA2FFF8B Mobile Hash is 603622DBF35C64F0B6FF15A75BF47F35A5B4DF83DDB84A35E9FFEE1EA6059DF3 Photo Exists : true Content Length is : 1129 Signature Verify Data call is true

srikanthlogic avatar Sep 12 '19 09:09 srikanthlogic

There seem to be some issue with photograph / needs clarity. I was unable to extract photograph successfully as well on my java util. Noting here as getting struck in photograph extraction might not be your mistake.

srikanthlogic avatar Oct 14 '19 11:10 srikanthlogic

I am always getting false for any signature validation.Can anybody help please?

My code is below:-

byte[] encoded = Base64.decodeBase64("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"); InputStream certstream = new ByteArrayInputStream(encoded); Certificate cert = CertificateFactory.getInstance("X.509").generateCertificate(certstream); PublicKey pkey = cert.getPublicKey(); boolean validsign = signvalidation(signbytes,sinvaluebyes,pkey);

public boolean signvalidation(byte[] signature,byte[] signvalue, PublicKey pkey) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException { Signature sign = Signature.getInstance("SHA256withRSA"); sign.initVerify(pkey); sign.update(signvalue); return sign.verify(signature); }

yogeshmallik avatar Feb 29 '20 12:02 yogeshmallik

boolean validsign = signvalidation(signbytes,sinvaluebyes,pkey);

I don't know what the distinction between signbytes and sinvaluebyes. But signvalidation method is correct if signature is the dataBytes part and signvalue is signatureBytes and you update signature object with dataBytes first and verify using the signatureBytes. I was able to verify signature for few QR I had come across. The same in UIDAI site though is erroneous.

srikanthlogic avatar Mar 01 '20 09:03 srikanthlogic

@srikanthlogic .. The signbytes is obtained by removal of the signature value from secure qr code byte array to get signed data. for(int i=0; i<decompressedBytes.length-256 ; i++) { sinvaluebyes[i] = decompressedBytes[i]; } The sinvaluebyes is obtained by reading the value of decompressed bytes from end (Byte array length -1) till 256 byte in reverse order. for(int i=0,j=decompressedBytes.length-1; i<256 & j>=decompressedBytes.length-256 ; i++,j--) { signbytes[i] = decompressedBytes[j]; }

This was the logic stated in the document. Is this logic correct?

yogeshmallik avatar Mar 02 '20 05:03 yogeshmallik

@srikanthlogic ... Can you please tell which public key are you using? Are you using the above public key?

yogeshmallik avatar Mar 03 '20 05:03 yogeshmallik

@srikanthlogic ... Can you please tell which public key are you using? Are you using the above public key?

I was using uidai_prod_cdup.cer linked in the first comment on thread.

This was the logic stated in the document. Is this logic correct?

You are right, but I think reading backwards is only for photo (the thing I haven't been able to successfully extract yet) and signature is just last 256 bytes in unreversed order. Please do let us know if you are able to extract photo too successfully.

srikanthlogic avatar Mar 03 '20 06:03 srikanthlogic

@srikanthlogic Thank you so much... I am able to do signature validation now. But, photo I am still not able to extract

yogeshmallik avatar Mar 03 '20 07:03 yogeshmallik

Hi I am trying to validate signature in the secure QR code but I am getting false value. I used the above certificates and uidai_12_06_18_cer.cer.

code of getting signature value__ for(int i=0,j = output.length-1; i<256 & j >= output.length-256 ; i++,j--){ signArray[i] = output[j]; } END__

signature verification method Signature signature = Signature.getInstance("SHA256withRSA"); InputStream in = getAssets().open("uidai.cer"); CertificateFactory certFactory = CertificateFactory.getInstance("X.509"); X509Certificate cer = (X509Certificate) certFactory.generateCertificate(in); PublicKey publicKey = cer.getPublicKey(); in.close(); signature.initVerify(publicKey); signature.update(dataSigned); isVerified = signature.verify(signArray); END__ I followed same validation steps given in the UIDAI pdf https://uidai.gov.in/images/resource/User_manulal_QR_Code_15032019.pdf. can any help me to figure out the mistake I am making. Thanks in advance.

UgandharTalari avatar Aug 01 '22 06:08 UgandharTalari