File indexing completed on 2024-12-22 04:57:52
0001 /* 0002 SPDX-FileCopyrightText: 2011 Andre Somers 0003 0004 SPDX-License-Identifier: BSD-3-Clause 0005 */ 0006 0007 #pragma once 0008 #include <QList> 0009 #include <QString> 0010 0011 /** 0012 @short Simple encryption and decryption of strings and byte arrays 0013 0014 This class provides a simple implementation of encryption and decryption 0015 of strings and byte arrays. 0016 0017 @warning The encryption provided by this class is NOT strong encryption. It may 0018 help to shield things from curious eyes, but it will NOT stand up to someone 0019 determined to break the encryption. Don't say you were not warned. 0020 0021 The class uses a 64 bit key. Simply create an instance of the class, set the key, 0022 and use the encryptToString() method to calculate an encrypted version of the input string. 0023 To decrypt that string again, use an instance of SimpleCrypt initialized with 0024 the same key, and call the decryptToString() method with the encrypted string. If the key 0025 matches, the decrypted version of the string will be returned again. 0026 0027 If you do not provide a key, or if something else is wrong, the encryption and 0028 decryption function will return an empty string or will return a string containing nonsense. 0029 lastError() will return a value indicating if the method was successful, and if not, why not. 0030 0031 SimpleCrypt is prepared for the case that the encryption and decryption 0032 algorithm is changed in a later version, by prepending a version identifier to the cypertext. 0033 */ 0034 class O0SimpleCrypt 0035 { 0036 public: 0037 /** 0038 CompressionMode describes if compression will be applied to the data to be 0039 encrypted. 0040 */ 0041 enum CompressionMode { 0042 CompressionAuto, /*!< Only apply compression if that results in a shorter plaintext. */ 0043 CompressionAlways, /*!< Always apply compression. Note that for short inputs, a compression may result in longer data */ 0044 CompressionNever /*!< Never apply compression. */ 0045 }; 0046 /** 0047 IntegrityProtectionMode describes measures taken to make it possible to detect problems with the data 0048 or wrong decryption keys. 0049 0050 Measures involve adding a checksum or a cryptograhpic hash to the data to be encrypted. This 0051 increases the length of the resulting cypertext, but makes it possible to check if the plaintext 0052 appears to be valid after decryption. 0053 */ 0054 enum IntegrityProtectionMode { 0055 ProtectionNone, /*!< The integrity of the encrypted data is not protected. It is not really possible to detect a wrong key, for instance. */ 0056 ProtectionChecksum, /*!< A simple checksum is used to verify that the data is in order. If not, an empty string is returned. */ 0057 ProtectionHash /*!< A cryptographic hash is used to verify the integrity of the data. This method produces a much stronger, but longer check */ 0058 }; 0059 /** 0060 Error describes the type of error that occurred. 0061 */ 0062 enum Error { 0063 ErrorNoError, /*!< No error occurred. */ 0064 ErrorNoKeySet, /*!< No key was set. You can not encrypt or decrypt without a valid key. */ 0065 ErrorUnknownVersion, /*!< The version of this data is unknown, or the data is otherwise not valid. */ 0066 ErrorIntegrityFailed /*!< The integrity check of the data failed. Perhaps the wrong key was used. */ 0067 }; 0068 0069 /** 0070 Constructor. 0071 0072 Constructs a SimpleCrypt instance without a valid key set on it. 0073 */ 0074 O0SimpleCrypt(); 0075 /** 0076 Constructor. 0077 0078 Constructs a SimpleCrypt instance and initializes it with the given @arg key. 0079 */ 0080 explicit O0SimpleCrypt(quint64 key); 0081 0082 /** 0083 (Re-) initializes the key with the given @arg key. 0084 */ 0085 void setKey(quint64 key); 0086 /** 0087 Returns true if SimpleCrypt has been initialized with a key. 0088 */ 0089 bool hasKey() const 0090 { 0091 return !m_keyParts.isEmpty(); 0092 } 0093 0094 /** 0095 Sets the compression mode to use when encrypting data. The default mode is Auto. 0096 0097 Note that decryption is not influenced by this mode, as the decryption recognizes 0098 what mode was used when encrypting. 0099 */ 0100 void setCompressionMode(CompressionMode mode) 0101 { 0102 m_compressionMode = mode; 0103 } 0104 0105 /** 0106 Returns the CompressionMode that is currently in use. 0107 */ 0108 CompressionMode compressionMode() const 0109 { 0110 return m_compressionMode; 0111 } 0112 0113 /** 0114 Sets the integrity mode to use when encrypting data. The default mode is Checksum. 0115 0116 Note that decryption is not influenced by this mode, as the decryption recognizes 0117 what mode was used when encrypting. 0118 */ 0119 void setIntegrityProtectionMode(IntegrityProtectionMode mode) 0120 { 0121 m_protectionMode = mode; 0122 } 0123 0124 /** 0125 Returns the IntegrityProtectionMode that is currently in use. 0126 */ 0127 IntegrityProtectionMode integrityProtectionMode() const 0128 { 0129 return m_protectionMode; 0130 } 0131 0132 /** 0133 Returns the last error that occurred. 0134 */ 0135 Error lastError() const 0136 { 0137 return m_lastError; 0138 } 0139 0140 /** 0141 Encrypts the @arg plaintext string with the key the class was initialized with, and returns 0142 a cyphertext the result. The result is a base64 encoded version of the binary array that is the 0143 actual result of the string, so it can be stored easily in a text format. 0144 */ 0145 QString encryptToString(const QString &plaintext); 0146 /** 0147 Encrypts the @arg plaintext QByteArray with the key the class was initialized with, and returns 0148 a cyphertext the result. The result is a base64 encoded version of the binary array that is the 0149 actual result of the encryption, so it can be stored easily in a text format. 0150 */ 0151 QString encryptToString(const QByteArray &plaintext); 0152 /** 0153 Encrypts the @arg plaintext string with the key the class was initialized with, and returns 0154 a binary cyphertext in a QByteArray the result. 0155 0156 This method returns a byte array, that is useable for storing a binary format. If you need 0157 a string you can store in a text file, use encryptToString() instead. 0158 */ 0159 QByteArray encryptToByteArray(const QString &plaintext); 0160 /** 0161 Encrypts the @arg plaintext QByteArray with the key the class was initialized with, and returns 0162 a binary cyphertext in a QByteArray the result. 0163 0164 This method returns a byte array, that is useable for storing a binary format. If you need 0165 a string you can store in a text file, use encryptToString() instead. 0166 */ 0167 QByteArray encryptToByteArray(const QByteArray &plaintext); 0168 0169 /** 0170 Decrypts a cyphertext string encrypted with this class with the set key back to the 0171 plain text version. 0172 0173 If an error occurred, such as non-matching keys between encryption and decryption, 0174 an empty string or a string containing nonsense may be returned. 0175 */ 0176 QString decryptToString(const QString &cyphertext); 0177 /** 0178 Decrypts a cyphertext string encrypted with this class with the set key back to the 0179 plain text version. 0180 0181 If an error occurred, such as non-matching keys between encryption and decryption, 0182 an empty string or a string containing nonsense may be returned. 0183 */ 0184 QByteArray decryptToByteArray(const QString &cyphertext); 0185 /** 0186 Decrypts a cyphertext binary encrypted with this class with the set key back to the 0187 plain text version. 0188 0189 If an error occurred, such as non-matching keys between encryption and decryption, 0190 an empty string or a string containing nonsense may be returned. 0191 */ 0192 QString decryptToString(const QByteArray &cypher); 0193 /** 0194 Decrypts a cyphertext binary encrypted with this class with the set key back to the 0195 plain text version. 0196 0197 If an error occurred, such as non-matching keys between encryption and decryption, 0198 an empty string or a string containing nonsense may be returned. 0199 */ 0200 QByteArray decryptToByteArray(const QByteArray &cypher); 0201 0202 // enum to describe options that have been used for the encryption. Currently only one, but 0203 // that only leaves room for future extensions like adding a cryptographic hash... 0204 enum CryptoFlag { 0205 CryptoFlagNone = 0, 0206 CryptoFlagCompression = 0x01, 0207 CryptoFlagChecksum = 0x02, 0208 CryptoFlagHash = 0x04, 0209 }; 0210 Q_DECLARE_FLAGS(CryptoFlags, CryptoFlag) 0211 private: 0212 void splitKey(); 0213 0214 quint64 m_key; 0215 QList<char> m_keyParts; 0216 CompressionMode m_compressionMode; 0217 IntegrityProtectionMode m_protectionMode; 0218 Error m_lastError; 0219 }; 0220 Q_DECLARE_OPERATORS_FOR_FLAGS(O0SimpleCrypt::CryptoFlags)