QxSimpleCrypt.h 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. /*
  2. Copyright (c) 2011, Andre Somers
  3. All rights reserved.
  4. Redistribution and use in source and binary forms, with or without
  5. modification, are permitted provided that the following conditions are met:
  6. * Redistributions of source code must retain the above copyright
  7. notice, this list of conditions and the following disclaimer.
  8. * Redistributions in binary form must reproduce the above copyright
  9. notice, this list of conditions and the following disclaimer in the
  10. documentation and/or other materials provided with the distribution.
  11. * Neither the name of the Rathenau Instituut, Andre Somers nor the
  12. names of its contributors may be used to endorse or promote products
  13. derived from this software without specific prior written permission.
  14. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  15. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  16. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  17. DISCLAIMED. IN NO EVENT SHALL ANDRE SOMERS BE LIABLE FOR ANY
  18. DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  19. (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  20. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  21. ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  22. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  23. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  24. */
  25. #ifndef _QX_SIMPLECRYPT_H_
  26. #define _QX_SIMPLECRYPT_H_
  27. #ifdef _MSC_VER
  28. #pragma once
  29. #endif
  30. /*!
  31. * \file QxSimpleCrypt.h
  32. * \author Andre Somers
  33. * \ingroup QxCommon
  34. * \brief qx::QxSimpleCrypt : simple encryption and decryption of strings and byte arrays
  35. */
  36. #include <QtCore/qglobal.h>
  37. #include <QtCore/qstring.h>
  38. #include <QtCore/qvector.h>
  39. #include <QtCore/qbytearray.h>
  40. namespace qx {
  41. /**
  42. @ingroup QxCommon
  43. @short Simple encryption and decryption of strings and byte arrays
  44. This class provides a simple implementation of encryption and decryption
  45. of strings and byte arrays : http://qt-project.org/wiki/Simple_encryption
  46. @warning The encryption provided by this class is NOT strong encryption. It may
  47. help to shield things from curious eyes, but it will NOT stand up to someone
  48. determined to break the encryption. Don't say you were not warned.
  49. The class uses a 64 bit key. Simply create an instance of the class, set the key,
  50. and use the encryptToString() method to calculate an encrypted version of the input string.
  51. To decrypt that string again, use an instance of QxSimpleCrypt initialized with
  52. the same key, and call the decryptToString() method with the encrypted string. If the key
  53. matches, the decrypted version of the string will be returned again.
  54. If you do not provide a key, or if something else is wrong, the encryption and
  55. decryption function will return an empty string or will return a string containing nonsense.
  56. lastError() will return a value indicating if the method was succesful, and if not, why not.
  57. QxSimpleCrypt is prepared for the case that the encryption and decryption
  58. algorithm is changed in a later version, by prepending a version identifier to the cypertext.
  59. */
  60. class QX_DLL_EXPORT QxSimpleCrypt
  61. {
  62. public:
  63. /**
  64. CompressionMode describes if compression will be applied to the data to be
  65. encrypted.
  66. */
  67. enum CompressionMode {
  68. CompressionAuto, /*!< Only apply compression if that results in a shorter plaintext. */
  69. CompressionAlways, /*!< Always apply compression. Note that for short inputs, a compression may result in longer data */
  70. CompressionNever /*!< Never apply compression. */
  71. };
  72. /**
  73. IntegrityProtectionMode describes measures taken to make it possible to detect problems with the data
  74. or wrong decryption keys.
  75. Measures involve adding a checksum or a cryptograhpic hash to the data to be encrypted. This
  76. increases the length of the resulting cypertext, but makes it possible to check if the plaintext
  77. appears to be valid after decryption.
  78. */
  79. enum IntegrityProtectionMode {
  80. ProtectionNone, /*!< The integerity of the encrypted data is not protected. It is not really possible to detect a wrong key, for instance. */
  81. ProtectionChecksum,/*!< A simple checksum is used to verify that the data is in order. If not, an empty string is returned. */
  82. ProtectionHash /*!< A cryptographic hash is used to verify the integrity of the data. This method produces a much stronger, but longer check */
  83. };
  84. /**
  85. Error describes the type of error that occured.
  86. */
  87. enum Error {
  88. ErrorNoError, /*!< No error occurred. */
  89. ErrorNoKeySet, /*!< No key was set. You can not encrypt or decrypt without a valid key. */
  90. ErrorUnknownVersion, /*!< The version of this data is unknown, or the data is otherwise not valid. */
  91. ErrorIntegrityFailed, /*!< The integrity check of the data failed. Perhaps the wrong key was used. */
  92. };
  93. /**
  94. Constructor.
  95. Constructs a QxSimpleCrypt instance without a valid key set on it.
  96. */
  97. QxSimpleCrypt();
  98. /**
  99. Constructor.
  100. Constructs a QxSimpleCrypt instance and initializes it with the given @arg key.
  101. */
  102. explicit QxSimpleCrypt(quint64 key);
  103. /**
  104. (Re-) initializes the key with the given @arg key.
  105. */
  106. void setKey(quint64 key);
  107. /**
  108. Returns true if QxSimpleCrypt has been initialized with a key.
  109. */
  110. bool hasKey() const {return !m_keyParts.isEmpty();}
  111. /**
  112. Sets the compression mode to use when encrypting data. The default mode is Auto.
  113. Note that decryption is not influenced by this mode, as the decryption recognizes
  114. what mode was used when encrypting.
  115. */
  116. void setCompressionMode(CompressionMode mode) {m_compressionMode = mode;}
  117. /**
  118. Returns the CompressionMode that is currently in use.
  119. */
  120. CompressionMode compressionMode() const {return m_compressionMode;}
  121. /**
  122. Sets the integrity mode to use when encrypting data. The default mode is Checksum.
  123. Note that decryption is not influenced by this mode, as the decryption recognizes
  124. what mode was used when encrypting.
  125. */
  126. void setIntegrityProtectionMode(IntegrityProtectionMode mode) {m_protectionMode = mode;}
  127. /**
  128. Returns the IntegrityProtectionMode that is currently in use.
  129. */
  130. IntegrityProtectionMode integrityProtectionMode() const {return m_protectionMode;}
  131. /**
  132. Returns the last error that occurred.
  133. */
  134. Error lastError() const {return m_lastError;}
  135. /**
  136. Encrypts the @arg plaintext string with the key the class was initialized with, and returns
  137. a cyphertext the result. The result is a base64 encoded version of the binary array that is the
  138. actual result of the string, so it can be stored easily in a text format.
  139. */
  140. QString encryptToString(const QString& plaintext) ;
  141. /**
  142. Encrypts the @arg plaintext QByteArray with the key the class was initialized with, and returns
  143. a cyphertext the result. The result is a base64 encoded version of the binary array that is the
  144. actual result of the encryption, so it can be stored easily in a text format.
  145. */
  146. QString encryptToString(QByteArray plaintext) ;
  147. /**
  148. Encrypts the @arg plaintext string with the key the class was initialized with, and returns
  149. a binary cyphertext in a QByteArray the result.
  150. This method returns a byte array, that is useable for storing a binary format. If you need
  151. a string you can store in a text file, use encryptToString() instead.
  152. */
  153. QByteArray encryptToByteArray(const QString& plaintext) ;
  154. /**
  155. Encrypts the @arg plaintext QByteArray with the key the class was initialized with, and returns
  156. a binary cyphertext in a QByteArray the result.
  157. This method returns a byte array, that is useable for storing a binary format. If you need
  158. a string you can store in a text file, use encryptToString() instead.
  159. */
  160. QByteArray encryptToByteArray(QByteArray plaintext) ;
  161. /**
  162. Decrypts a cyphertext string encrypted with this class with the set key back to the
  163. plain text version.
  164. If an error occured, such as non-matching keys between encryption and decryption,
  165. an empty string or a string containing nonsense may be returned.
  166. */
  167. QString decryptToString(const QString& cyphertext) ;
  168. /**
  169. Decrypts a cyphertext string encrypted with this class with the set key back to the
  170. plain text version.
  171. If an error occured, such as non-matching keys between encryption and decryption,
  172. an empty string or a string containing nonsense may be returned.
  173. */
  174. QByteArray decryptToByteArray(const QString& cyphertext) ;
  175. /**
  176. Decrypts a cyphertext binary encrypted with this class with the set key back to the
  177. plain text version.
  178. If an error occured, such as non-matching keys between encryption and decryption,
  179. an empty string or a string containing nonsense may be returned.
  180. */
  181. QString decryptToString(QByteArray cypher) ;
  182. /**
  183. Decrypts a cyphertext binary encrypted with this class with the set key back to the
  184. plain text version.
  185. If an error occured, such as non-matching keys between encryption and decryption,
  186. an empty string or a string containing nonsense may be returned.
  187. */
  188. QByteArray decryptToByteArray(QByteArray cypher) ;
  189. // enum to describe options that have been used for the encryption. Currently only one, but
  190. // that only leaves room for future extensions like adding a cryptographic hash...
  191. enum CryptoFlag{CryptoFlagNone = 0,
  192. CryptoFlagCompression = 0x01,
  193. CryptoFlagChecksum = 0x02,
  194. CryptoFlagHash = 0x04
  195. };
  196. Q_DECLARE_FLAGS(CryptoFlags, CryptoFlag);
  197. private:
  198. void splitKey();
  199. quint64 m_key;
  200. QVector<char> m_keyParts;
  201. CompressionMode m_compressionMode;
  202. IntegrityProtectionMode m_protectionMode;
  203. Error m_lastError;
  204. };
  205. } // namespace qx
  206. Q_DECLARE_OPERATORS_FOR_FLAGS(qx::QxSimpleCrypt::CryptoFlags)
  207. #endif // _QX_SIMPLECRYPT_H_