1

​Hi All,

I have a requirement where the client application is expected to send the data through the rest api end point provided by us. Client application is expected to send the data as query parameters.

curl -L -X POST "http://endpointurl:port/data?result=PASS&c=ADD_RECORD&attribute1=test1&attribute2=test2&attribute3=test3&attribute4=test4&signature=62759010b083d8fcf6e7ec18e6582bc07789d6dda17efbff6f474635c63db6afcbb3a0c25cf0d4c5bb1ba0ab772124edb9ba064d1530c2848fc160546263c86a2ba0cc26dd0073bb6344a1abb7475bcb1cd9f1c2b6af750db043a3da807ca356ab2d0959719dfff28af16246ce242a71d9fc99e5c383edfa90f6426568e1b6e9f8510871e40a05f6debaa6d9eee72eb9f6e0691ec625b1b24bb49cb3840940e7f83a13cdc0022e4a8ac35866f9b74418dcbeb232962113ad765cce334f431108866753c767098c363f97c056fa5f377b04094436629e9ede71b3074766c5b7492e4d7d5f4f52af0bee1683af68bb70f3cda4fef78cf5f98ce8765fd5d0e12280"

Along with the all the elements/columns of actual data(result, attribute1, attribute2, attribute3 and attribute4 client application would also send one addition parameter called signature which is created by hashing and creating the signature using client side private key based on the key parameters(not all the query parameters)

Signature: echo -n 'attribute1attribute3' | openssl sha1 -sign id_rsa -hex

Client application also provided the public key file for us to validate the signature with the actual data before wee process the records.

I am using apache nifi on HDP with below high level flow. Have used some other processors for validations and to allow other http requests.

Handlehttprequest-->>AttributestoJson-->>RouteOnAttribute-->>JolttransformJSON-->>ReplaceText-->>PutKafka-->>HandlehttpResponse

Basically, I am extracting all the http.query.param values from the data posted, and if parameter C=ADD_RECORD, I am concatenating the key attributes (attribute1, attribute3) which would be the actual data which should be verified against the signature value.

I tried to go through hashcontent processor with SHA1 but the hash value that i get is very small and it is not derived based on the client provided public key.

I also tried looking at the python scripts using Crypto package, but not been able to verify the signature with the actual data. On top of that, I am not sure, how can i call python script inside nifi.

Below are the commands that I can use manually to validate the signature with the data

echo -n 'attribute1attribute3' | openssl sha1 -sign id_rsa -hex>signature.hex

xxd -r -p signature.hex > signature.bin

echo -n 'attribute1attribute3'>keyattribute.txt

openssl dgst -sha1 -verify /tmp/test.pub -signature signature.bin keyattribute.txt and signature.bin to verify the digital signature., but in my actual requirement, I would be getting all these data as query parameters.

Need help in providing insights with respect to below.

Hashcontent can be used to generate the signature based on the public.key file? if so, I think we can use Routeonattribute to verify the signature with the actual value and take necessary actions.

Any guidance on achieving this by python/Groovy/Jython script and idea on how it can be called with in Nifi pipeline?

Any possibility of building the custom processor for meeting this requirement?

Appreciate any help on this.

Thanks,

Vish

==================================== Hi All,

In addition to my earlier query, I could finally get the python script up and running which takes three arguments

  1. pub.key file location

  2. signature value from hexdump from the client side

  3. actual concatenated fields of key columns on which the signature is generated.

and displays whether the signature matches or fails.

from __future__ import print_function, unicode_literals
import sys
import binascii
from Crypto.PublicKey import RSA
from Crypto.Signature import PKCS1_v1_5
from Crypto.Hash import SHA
pubfile = sys.argv[1]
sig_hex = sys.argv[2]
data = sys.argv[3]
if not path.isfile(pubfile):
sys.stderr.write('public key file not found\n')
def verifier(pubkey, sig, data):
rsakey = RSA.importKey(key)
signer = PKCS1_v1_5.new(rsakey)
digest = SHA.new()
digest.update(data)
return signer.verify(digest, sig)

with open("pubfile", 'rb') as f: key = f.read()
sig = sig_hex.strip().decode('hex')

if verifier(key, sig, data):
print("Verified OK")
else:
print("Verification Failure")

Now need to know how can this be called with in nifi? and how can I pass the flow file attributes as arguments to the script (execute script processor) ? and how can I get the verification status message as additional attribute in the flow file?

Any help is greatly appreciated.

Thanks,

Vish

============================================================

OneCricketeer
  • 179,855
  • 19
  • 132
  • 245

1 Answers1

0

You can do this in a few ways. Since you already have a working series of shell commands, you can use the ExecuteStreamCommand processor to execute the series of commands (or wrap them in a shell script) and stream the incoming flowfile content to STDIN and stream STDOUT to the outgoing flowfile content.

If you prefer, you can use ExecuteScript or InvokeScriptedProcessor to run the DSL script you've written. I would recommend switching to use Groovy, as it is handled much better in current Apache NiFi releases. Python (actually Jython) is much slower and does not have access to native libraries.

Finally, you could write a custom processor to do this if it's a repeated task you'll need in future flows. There are many guides for writing a custom processor available online.

Andy
  • 13,916
  • 1
  • 36
  • 78
  • Thanks a lot @Andy for the inputs. any pointers to show how to pass/ use STDIN and STDOUT to get and post the content to flowfile? – vishwanatha handadi Jul 14 '18 at 06:32
  • Also HashCOntent processor can not be used for getting the hash values ? looking at the configuration properties, i see it supports SHA1, but did not see the ways to pass the public key that it can use to build hash value. I understood that this processor is widely used for identifying duplicates. But not sure, hash generated is different ? – vishwanatha handadi Jul 14 '18 at 06:34
  • STDIN and STDOUT are automatically used as the input/output of the shell command, so you don’t need to do anything special. Write the shell command to read/write that way, and the flowfiles will automatically populate/be populated. As for `HashContent`, that can calculate a SHA-1 hash, but verifying the signature is not part of its duties. – Andy Jul 14 '18 at 07:59
  • Thanks Again @Andy for the details. I will try out the options provided. – vishwanatha handadi Jul 16 '18 at 07:33