An advanced all-in-one QR code package that provides multiple layers of security. This package acts as a wrapper around some of the most popular QR-code related packages. It uses qr_flutter for rendering the QR-codes and mobile_scanner for reading the QR-codes.
An example QR code rendered with QrPlusMode.paranoid
Android | iOS | macOS | Web | Linux | Windows |
---|---|---|---|---|---|
✔ | ✔ | ✔ | ✔ | ❌ | ❌ |
Android | iOS | macOS | Web | Linux | Windows |
---|---|---|---|---|---|
✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
In today's world, QR codes are used for a wide range of purposes, from making payments to accessing secure information. However, the ease of use and convenience offered by QR codes also makes them vulnerable to malicious attacks. To address these security concerns, QR Plus provides multiple layers of security, each fixing a single security vulnerability from the previous layer, to ensure that your data is safe and sound.
For example, consider a scenario where you're organizing a scavenger hunt event and you want to ensure that each team's progress is recorded accurately and fairly. The teams will scan QR codes at various locations to receive points. To prevent cheating, you need a solution that ensures that each team only gets points for the location they have actually visited. This, and plenty of other similar use-cases, is why we created qr_plus; To make QR-codes safe without having to write a ton of own custom logic!
IMPORTANT: You need to have the same security mode on BOTH the reader and renderer, otherwise the reader won't accept the data.
Since this package is a wrapper around mobile_scanner, please follow the steps for platform specific configuration from their documentation.
QrPlusRenderer(
data: 'https://youtu.be/dQw4w9WgXcQ',
mode: const QrPlusMode.snowden(
encryptionKey: '<your-encryption-key>', // Your encryption key from .env. See https://pub.dev/packages/flutter_dotenv
),
),
QrPlusReader(
mode: const QrPlusMode.snowden(
encryptionKey: '<your-encryption-key>', // Your encryption key from .env. See https://pub.dev/packages/flutter_dotenv
),
onData: (data, authenticity) {
/// Handle the data
},
),
Enjoy your new safe QR-codes.
QR Plus offers multiple layers of security, each fixing a single security vulnerability from the previous layer. As you climb up the layers, the QR-codes become more and more secure. Here are the security layers within this package, from least to most secure:
This layer does not contain any security whatsoever.
A malicious user could screenshot the QR-code. In the scenario described in the Motivation section, a user could show a screenshot of a QR-code to a referee, which would give points to another user instead of the one who shows the QR-code.
This layer splits the data into multiple pieces and displays a single piece at a time.
A malicious user could screen record the changing QR-codes and share them with friends.
This layer adds a time-to-live (TTL) to the transmitted data. The QR-code is only valid for a given period of time. If the TTL has expired, the reader will be notified of that. Its up to the developer / user to decide what to do with that information.
A malicious user could modify the phone's time zone in the settings to display a QR-code that is valid in the future.
This layer adds time synchronization from a remote NTP server. The user can change the time settings locally, but it won't affect the QR-code.
A malicious user could share their screen in a FaceTime call or turn off network connections to trick TTL and NTP.
This layer adds possible cheating attempt detection. The renderer knows when the device is currently sharing its screen or recording it, or when the user has turned off their network connection. The renderer (malicious user's phone) displays the QR-code normally, but information about this suspicious activity is sent to the reader through the QR-code. It is then up to the reader to decide what to do with this information.
A malicious user could read the data with another QR-code reader, manipulate the JSON to be valid, and create new QR-codes with the valid data.
This layer encrypts the data before sending it. With the encryption key properly stored, only the reader provided by this package can decrypt it.