Photo Signature#
ANAFI Ai allows signing photos with the embedded secure element.
The digital signature can prove the authenticity and integrity of any photo taken by the drone; both for the image itself and the associated EXIF and XMP metadata. The metadata includes:
the serial number of the drone,
the GPS location,
the photo capture timestamp,
the unique Common Name of the drone certificate.
Once the photo’s digital signature has been verified, one can prove to a client, a court, or any other third party that the picture was taken by a specific drone, at a specific time and location and that this picture has not been modified since.
More security information can be found here: https://developer.parrot.com/docs/airsdk/general/security.html.
Signatures and certificates#
When the digital signature of photos is enabled, photos have an XMP metadata
called Xmp.drone-parrot.SecureCn
, which value is the common name of the
drone certificate.
Each photo that is signed comes with a signature that has the same file name and a signature extension that depends on the photo file format:
Photo file name |
Signature file name |
---|---|
0123456_photo.JPG |
0123456_photo.SIG |
0123456_photo.DNG |
0123456_photo.DIG |
The signature file contains a digest of the photo, signed using the embedded secure element.
The drone certificate that contains the drone public key is available through the webserver API, with the following URL:
http://<drone_url>/api/v1/secure-element/drone.der
The DER certificate format is a binary file, it can be converted to PEM which is a human-readable format, with OpenSSL:
openssl x509 -inform DER -in drone.der -outform PEM -out drone.pem
This drone certificate is issued by the Parrot Drones Certificate Authority. Any drone certificate authenticity can be verified using this root certificate available here: https://developer.parrot.com/docs/downloads/ca-anafi-ai.pem
Verify a signature#
Signatures can be manually verified using command-line tools such as OpenSSL.
The steps to verify the digital signature of a photo are:
Extract from the photo’s metadata the Common Name of the certificate used to sign the picture,
Verify that the Common Name extracted from the metadata matches the drone certificate serial,
Check that the drone certificate has been issued by the Parrot Drones Certificate Authority,
Check the photo’s digital signature.
First, the Common Name of the drone certificate should be extracted from
the Xmp.drone-parrot.SecureCn
metadata. This can be done with the
exiv2
tool:
With:
0123456_photo.JPG
: the photo file
exiv2 -K Xmp.drone-parrot.SecureCn -px 0123456_photo.JPG
The drone certificate serial number can be extracted using OpenSSL:
With:
drones.pem
: the drone certificate in PEM format
openssl x509 -serial -noout -in drone.pem
After that, the drone certificate must be verified using the Parrot Drones Certificate Authority file:
With:
cadrones.pem
: the Parrot Drones Certificate Authority file in PEM formatdrone.pem
: the drone certificate in PEM format
openssl verify -CAfile cadrones.pem drone.pem
Now that the drone certificate has been authenticated, the following command can be executed to verify that a photo signature is authentic:
With:
drone.pem
: the drone certificate in PEM format0123456_photo.SIG
: the photo signature file0123456_photo.JPG
: the photo file
openssl dgst -sha256 \
-verify <(openssl x509 -in drone.pem -pubkey -noout) \
-signature 0123456_photo.SIG 0123456_photo.JPG
Felindra#
The felindra Python module provides both a library and an executable to verify the authenticity and integrity of any signed photo taken by an ANAFI Ai. The tool can verify photos remotely on a drone by using the webserver API or offline, by checking a directory and its subdirectories.
The felindra source code is public and available on the Parrot for Developers GitHub: https://github.com/Parrot-Developers/felindra
Download the Python module#
With python3:
python3 -m pip install parrot-felindra
Run the executable#
As a binary:
felindra [-h] [-v] {remote,local}
Or with python3 as a module:
python3 -m felindra [-h] [-v] {remote,local}
Verify signatures on drone#
If no IP address is provided, the script will automatically check common
ANAFI Ai IP addresses. Use -S
, --skip
to skip media that do not have
signatures (unsigned photos and videos).
python3 -m felindra remote [ip_addr]
Verify signatures offline#
Verify a single photo
The signature path is optional. If not set, the script will search for
<photo_filename_without_ext>.SIG
.
python3 -m felindra local \
<path_to_photo> <path_to_certificate> -s [path_to_signature]
The function returns True if the signature is authentic, otherwise False.
Verify a whole directory including its subdirectories
The script will iterate over all subdirectories of photo_directory
,
checking for photos.
python3 -m felindra local <photo_directory> <path_to_certificate>
Import the library#
Verify signatures on drone#
from felindra import verify_on_remote
ret = verify_on_remote()
The function returns a Python dictionary that contains all resources and
a summary of ok_count
, ko_count
and unsigned_count
.
Here is a sample:
{
"resources":{
"1004683_photo.JPG":{
"signed":true,
"valid_signature":true
},
"1004684_photo.JPG":{
"signed":false
},
"1004685_photo.JPG":{
"signed":true,
"valid_signature":false,
"reason":"invalid signature"
},
...
},
"ok_count":19,
"ko_count":2,
"unsigned_count":34
}
Verify signatures offline#
Verify a single photo
from felindra import verify_single
ret = verify_single(res_path=..., crt_path=...)
The function returns True
if the signature is authentic, otherwise False
.
Verify a whole directory and its subdirectories
from felindra import verify_on_disk
ret = verify_on_disk(res_path=..., crt_path=...)
The function returns a Python dictionary that contains all resources and
a summary of ok_count
, ko_count
and unsigned_count
.