Skip to content
Snippets Groups Projects
Verified Commit 2f1403a2 authored by Anian Bühler's avatar Anian Bühler
Browse files

added en-/decrypt to symetric with CS

parent 4aed8c15
No related branches found
No related tags found
No related merge requests found
#include "Arduino.h"
#include <DidacticEnc.h>
DidacticEncSymetric symEncrypt;
void setup()
{
Serial.begin(9600);
char cypherText[MAX_LEN_CYPHERTEXT] = {0};
char plainText[MAX_LEN_PLAINTEXT] = {0};
char key[] = "12345678";
Serial.print("Key:\t\t");
Serial.println(key);
char text[] = "Hallo letsgoING";
Serial.print("Original:\t");
Serial.println(text);
// Verchluesseln
symEncrypt.crypt(text, cypherText, key);
Serial.print("Verschluesselt:\t");
Serial.println(cypherText);
// Entschluesseln
symEncrypt.crypt(cypherText, plainText, key);
Serial.print("Entschlüsselt:\t");
Serial.println(plainText);
}
void loop()
{
// put your main code here, to run repeatedly:
}
\ No newline at end of file
......@@ -2,27 +2,36 @@
DidacticEncSymetric symEncrypt;
void setup() {
Serial.begin(9600);
char cypherText[MAX_LEN_CYPHERTEXT] ={0};
char plainText[MAX_LEN_PLAINTEXT] ={0};
char key[] = "12345678";
Serial.print("Key:\t\t");Serial.println(key);
char text[] = "Hallo letsgoING";
Serial.print("Original:\t");Serial.println(text);
//Verchluesseln
symEncrypt.crypt(text, cypherText, key);
Serial.print("Verschluesselt:\t");Serial.println(cypherText);
//Entschluesseln
symEncrypt.crypt(cypherText, plainText, key);
Serial.print("Entschlüsselt:\t");Serial.println(plainText);
}
void loop() {
// put your main code here, to run repeatedly:
}
void setup()
{
Serial.begin(9600);
char cypherText[MAX_LEN_CYPHERTEXT] = {0};
char plainText[MAX_LEN_PLAINTEXT] = {0};
char key[] = "12345678";
char testMark = 'T';
Serial.print("Key:\t\t");
Serial.println(key);
Serial.print("Test mark:\t\t");
Serial.println(testMark);
char text[] = "Hallo letsgoING";
Serial.print("Original:\t");
Serial.println(text);
// Verchluesseln
symEncrypt.encrypt(text, cypherText, key, testMark);
Serial.print("Verschluesselt:\t");
Serial.println(cypherText);
// Entschluesseln
symEncrypt.decrypt(cypherText, plainText, key, testMark);
Serial.print("Entschlüsselt:\t");
Serial.println(plainText);
void loop()
{
// put your main code here, to run repeatedly:
}
......@@ -8,55 +8,146 @@
#include "Arduino.h"
#include "DidacticEnc.h"
//**************************************************************************
//SYMETRIC
// SYMETRIC
//**************************************************************************
DidacticEncSymetric::DidacticEncSymetric(){}
DidacticEncSymetric::~DidacticEncSymetric(){}
DidacticEncSymetric::DidacticEncSymetric() {}
DidacticEncSymetric::~DidacticEncSymetric() {}
int DidacticEncSymetric::setKey(char* key){
if(strlen(key) == DE_LENGHT_KEY){
memcpy(_key, key, DE_LENGHT_KEY+1);
// Speichere Schlüssel
int DidacticEncSymetric::setKey(char *key)
{
if (strlen(key) >= MIN_LEN_KEY && strlen(key) <= MAX_LEN_KEY) // NEW
{
memcpy(_key, key, strlen(key));
return DE_ERROR_NOERROR;
} else if(strlen(key) > DE_LENGHT_KEY){
}
else if (strlen(key) > MAX_LEN_KEY)
{
return DE_ERROR_KEYLENGHT_LONG;
} else{
}
else
{
return DE_ERROR_KEYLENGHT_SHORT;
}
}
//Nachricht wird entschlüsselt und überschrieben
void DidacticEncSymetric::crypt(char* messageIn, int lengthMessage, char* messageOut, char* key, int lengthKey){
//ACHTUNG: bei gleichem Zeichen in Schlüssel und Nachricht wird die Nachricht unterbrochen
// Speichere Prüfzeichen
void DidacticEncSymetric::setTestMark(char mark) // NEW
{
_mark = mark;
}
// Nachricht wird entschlüsselt und überschrieben
void DidacticEncSymetric::crypt(char *messageIn, int lengthMessage, char *messageOut, char *key, int lengthKey)
{
// ACHTUNG: bei gleichem Zeichen in Schlüssel und Nachricht wird die Nachricht unterbrochen
int keyCounter = 0;
int msgCounter = 0;
for (msgCounter = 0; msgCounter < lengthMessage; msgCounter++) {
keyCounter = msgCounter % lengthKey; //Zähler für key der nie größer wird als lengthKey (Restwert der Division durch Schlüssellänge)
messageOut[msgCounter] = messageIn[msgCounter] ^ key[keyCounter]; //XOR-Verknüpfung
for (msgCounter = 0; msgCounter < lengthMessage; msgCounter++)
{
keyCounter = msgCounter % lengthKey; // Zähler für key der nie größer wird als lengthKey (Restwert der Division durch Schlüssellänge)
messageOut[msgCounter] = messageIn[msgCounter] ^ key[keyCounter]; // XOR-Verknüpfung
}
messageOut[msgCounter + 1] = '\0'; //"EndOfString" an letzter Stelle
messageOut[msgCounter] = '\0'; //"EndOfString" an letzter Stelle
}
void DidacticEncSymetric::crypt(char* messageIn, char* messageOut, char* key){
crypt(messageIn, strlen(messageIn), messageOut, key, strlen(key) );
void DidacticEncSymetric::crypt(char *messageIn, char *messageOut, char *key)
{
crypt(messageIn, strlen(messageIn), messageOut, key, strlen(key));
}
void DidacticEncSymetric::crypt(char* messageIn, char* messageOut){
void DidacticEncSymetric::crypt(char *messageIn, char *messageOut)
{
crypt(messageIn, strlen(messageIn), messageOut, _key, strlen(_key));
}
// ENCRYPT with additional checksum, test mark and second round XOR
void DidacticEncSymetric::encrypt(char *messageIn, int lengthMessage, char *messageOut, char *key, int lengthKey, char mark)
{
int keyCounter = 0;
int msgCounter = 0;
int checksum = 0;
messageOut[0] = key[lengthKey - 1]; // letztes Zeichen vom Schlüssel als Prüfzeichen
for (msgCounter = 0; msgCounter < lengthMessage; msgCounter++)
{
keyCounter = msgCounter % lengthKey - 1; // Zähler für key der nie größer wird als lengthKey-1 da letztes Zeichen als Prüfzeichen dient
messageOut[msgCounter + 1] = messageIn[msgCounter] ^ key[keyCounter]; // XOR-Verknüpfung
checksum += messageIn[msgCounter]; // Berechne Prüfsumme
}
checksum = checksum & B00111111; // Stelle sicher, dass die Prüfsumme nur 6 Bits hat (char hat 7 Bit und Ergebnis wird um 1 nach oben verschoben)
checksum = (checksum << 1) | 0b00000001; // Verschiebe die Prüfsumme um 1 Bit nach oben und setze das niedrigste auf 1
for (msgCounter = 0; msgCounter < lengthMessage + 1; msgCounter++) //+1 wegen zusätzlichem Prüfzeichen an erster Stelle
{
messageOut[msgCounter] = messageOut[msgCounter] ^ checksum; // XOR-Verknüpfung mit Prüfsumme
}
messageOut[msgCounter] = '\0'; //"EndOfString" an letzter Stelle
}
void DidacticEncSymetric::encrypt(char *messageIn, char *messageOut, char *key, char mark)
{
encrypt(messageIn, strlen(messageIn), messageOut, key, strlen(key), mark);
}
void DidacticEncSymetric::encrypt(char *messageIn, char *messageOut)
{
encrypt(messageIn, strlen(messageIn), messageOut, _key, strlen(_key), _mark);
}
// DECRYPT with additional checksum, test mark and second round XOR
bool DidacticEncSymetric::decrypt(char *messageIn, int lengthMessage, char *messageOut, char *key, int lengthKey, char mark)
{
int keyCounter = 0;
int msgCounter = 0;
int ownChecksum = 0;
int msgChecksum = messageIn[0] ^ key[lengthKey - 1]; // berechne übertragene Prüfsumme mit Prüfzeichen
for (msgCounter = 0; msgCounter < lengthMessage - 1; msgCounter++) //-1 wegen zusätzlichem Prüfzeichen an erster Stelle
{
messageOut[msgCounter] = messageIn[msgCounter + 1] ^ msgChecksum; // XOR-Verknüpfung mit Prüfsumme
}
messageOut[msgCounter] = '\0';
for (msgCounter = 0; msgCounter < lengthMessage - 1; msgCounter++)
{
keyCounter = msgCounter % lengthKey - 1; // Zähler für key der nie größer wird als lengthKey (Restwert der Division durch Schlüssellänge)
messageOut[msgCounter] = messageOut[msgCounter] ^ key[keyCounter]; // XOR-Verknüpfung
ownChecksum += messageOut[msgCounter]; // Berechne Prüfsumme
}
ownChecksum = ownChecksum & B00111111; // Stelle sicher, dass die Prüfsumme nur 6 Bits hat (char hat 7 Bit und Ergebnis wird um 1 nach oben verschoben)
ownChecksum = (ownChecksum << 1) | 0b00000001; // Verschiebe die Prüfsumme um 1 Bit nach oben und setze das niedrigste auf 1
messageOut[msgCounter] = '\0'; //"EndOfString" an letzter Stelle
return ownChecksum == msgChecksum;
}
bool DidacticEncSymetric::decrypt(char *messageIn, char *messageOut, char *key, char mark)
{
return decrypt(messageIn, strlen(messageIn), messageOut, key, strlen(key), mark);
}
bool DidacticEncSymetric::decrypt(char *messageIn, char *messageOut)
{
return decrypt(messageIn, strlen(messageIn), messageOut, _key, strlen(_key), _mark);
}
//**************************************************************************
//ASYMETRIC
// ASYMETRIC
//**************************************************************************
DidacticEncAsymetric::DidacticEncAsymetric(){}
DidacticEncAsymetric::~DidacticEncAsymetric(){}
DidacticEncAsymetric::DidacticEncAsymetric() {}
DidacticEncAsymetric::~DidacticEncAsymetric() {}
void DidacticEncAsymetric::generateRsaKeys(long p, long q, long& n, long& e, long& d) {
void DidacticEncAsymetric::generateRsaKeys(long p, long q, long &n, long &e, long &d)
{
long x = 0;
long y = 0;
long m = 0;
......@@ -64,80 +155,97 @@ void DidacticEncAsymetric::generateRsaKeys(long p, long q, long& n, long& e, lon
n = p * q;
m = (p - 1) * (q - 1);
e = 3; //start value
while (gcd(e, m) > 1) {
e = 3; // start value
while (gcd(e, m) > 1)
{
e += 2;
}
if (egcd(e, m, x, y) == 1) {
if (x < 0) {
if (egcd(e, m, x, y) == 1)
{
if (x < 0)
{
x += m;
}
d = x % m;
}
}
long DidacticEncAsymetric::cryptRsa(long key, long n, long message) {
long DidacticEncAsymetric::cryptRsa(long key, long n, long message)
{
return modPow(message, key, n);
}
long DidacticEncAsymetric::getPrime(){
return prime[random(0, MAX_NR_OF_PRIMES- MAX_PRIME_OFFSET)];
long DidacticEncAsymetric::getPrime()
{
return prime[random(0, MAX_NR_OF_PRIMES - MAX_PRIME_OFFSET)];
}
long DidacticEncAsymetric::getPrimeWithOffset(long basicPrime){
long DidacticEncAsymetric::getPrimeWithOffset(long basicPrime)
{
int index = 0;
while(prime[index] != basicPrime && index <= MAX_NR_OF_PRIMES- MAX_PRIME_OFFSET){
while (prime[index] != basicPrime && index <= MAX_NR_OF_PRIMES - MAX_PRIME_OFFSET)
{
++index;
}
return prime[index + random(1,MAX_PRIME_OFFSET)];
return prime[index + random(1, MAX_PRIME_OFFSET)];
}
void DidacticEncAsymetric::setRandomSeedPin(int analogPin){
if(analogPin <= A5 && analogPin >= A0){
_randomPin = analogPin;
void DidacticEncAsymetric::setRandomSeedPin(int analogPin)
{
if (analogPin <= A5 && analogPin >= A0)
{
_randomPin = analogPin;
}
}
void DidacticEncAsymetric::generateKeys(){
void DidacticEncAsymetric::generateKeys()
{
randomSeed(analogRead(_randomPin));
long firstPrime = getPrime();
long secondPrime = getPrimeWithOffset(firstPrime);
generateRsaKeys(firstPrime, secondPrime, _rsaModule, _publicKey, _privateKey);
long firstPrime = getPrime();
long secondPrime = getPrimeWithOffset(firstPrime);
generateRsaKeys(firstPrime, secondPrime, _rsaModule, _publicKey, _privateKey);
}
long DidacticEncAsymetric::getPrivateKey(){
long DidacticEncAsymetric::getPrivateKey()
{
return _privateKey;
}
long DidacticEncAsymetric::getPublicKey(){
return _publicKey;
long DidacticEncAsymetric::getPublicKey()
{
return _publicKey;
}
long DidacticEncAsymetric::getRsaModule(){
long DidacticEncAsymetric::getRsaModule()
{
return _rsaModule;
}
int DidacticEncAsymetric::encrypt(char* plainText, int lengthplainText, char* cypherText, long key, long rsaModule){
for(int i = 0; i< lengthplainText; ++i){
long currentMessage = (long) plainText[i];
snprintf(&(cypherText[strlen(cypherText)]), MAX_LEN_CYPHERTEXT, "%ld", cryptRsa( key, rsaModule, currentMessage));
snprintf(&(cypherText[strlen(cypherText)]), MAX_LEN_CYPHERTEXT, DE_CYPHER_SEPARATOR);
}
return strlen(cypherText);
int DidacticEncAsymetric::encrypt(char *plainText, int lengthplainText, char *cypherText, long key, long rsaModule)
{
for (int i = 0; i < lengthplainText; ++i)
{
long currentMessage = (long)plainText[i];
snprintf(&(cypherText[strlen(cypherText)]), MAX_LEN_CYPHERTEXT, "%ld", cryptRsa(key, rsaModule, currentMessage));
snprintf(&(cypherText[strlen(cypherText)]), MAX_LEN_CYPHERTEXT, DE_CYPHER_SEPARATOR);
}
return strlen(cypherText);
}
int DidacticEncAsymetric::encrypt(char* plainText, char* cypherText, long key, long rsaModule){
int DidacticEncAsymetric::encrypt(char *plainText, char *cypherText, long key, long rsaModule)
{
return encrypt(plainText, strlen(plainText), cypherText, key, rsaModule);
}
int DidacticEncAsymetric::decrypt(char* cypherText, char* plainText, long key, long rsaModule) {
int DidacticEncAsymetric::decrypt(char *cypherText, char *plainText, long key, long rsaModule)
{
char *currentNumber;
char *savePointer = cypherText;
int counter = 0;
while ((currentNumber = strtok_r(savePointer, DE_CYPHER_SEPARATOR, &savePointer)) != NULL) // Don't use \n here it fails
while ((currentNumber = strtok_r(savePointer, DE_CYPHER_SEPARATOR, &savePointer)) != NULL) // Don't use \n here it fails
{
long number = atol(currentNumber);
plainText[counter] = cryptRsa( key, rsaModule, number);
plainText[counter] = cryptRsa(key, rsaModule, number);
++counter;
}
plainText[counter] = '\0';
......@@ -145,15 +253,16 @@ int DidacticEncAsymetric::decrypt(char* cypherText, char* plainText, long key, l
}
//***************
/**********************************************
* MATH FUNCTIONS FOR RSA
**********************************************/
// Basic Euclidean Algorithm for greatest common divider
long DidacticEncAsymetric::gcd (long a, long b) {
long DidacticEncAsymetric::gcd(long a, long b)
{
long r;
while (b != 0) {
while (b != 0)
{
r = a % b;
a = b;
b = r;
......@@ -170,7 +279,8 @@ long DidacticEncAsymetric::gcd (long a, long b) {
} */
// extended euclidean algorithm: also finds coefficients x and y
long DidacticEncAsymetric::egcd (long a, long b, long& x, long& y){
long DidacticEncAsymetric::egcd(long a, long b, long &x, long &y)
{
if (a == 0)
{
x = 0;
......@@ -187,17 +297,17 @@ long DidacticEncAsymetric::egcd (long a, long b, long& x, long& y){
return gcd;
}
//modular exponentation (to keep values as small as possible)
long DidacticEncAsymetric::modPow(long base, long exponent, long modulus) {
if (modulus == 1) {
// modular exponentation (to keep values as small as possible)
long DidacticEncAsymetric::modPow(long base, long exponent, long modulus)
{
if (modulus == 1)
{
return 0;
}
long c = 1;
for (long i = 0; i < exponent; i++) {
for (long i = 0; i < exponent; i++)
{
c = c * base % modulus;
}
return c;
}
/**************************************************************************
@file didacticNet.h
@author anian buehler @ letsgoING
@file didacticNet.h
@author anian buehler @ letsgoING
**************************************************************************/
#ifndef _DIDACTICENC_
#define _DIDACTICENC_
#include "Arduino.h"
class DidacticEncSymetric
{
#define DE_LENGHT_KEY 8
// NEW #define DE_LENGHT_KEY 8
#define MAX_LEN_CYPHERTEXT DE_LENGHT_KEY*4
#define MAX_LEN_PLAINTEXT DE_LENGHT_KEY*4
#define MIN_LEN_KEY 5 // NEW
#define MAX_LEN_KEY 20 // NEW
#define MAX_LEN_CYPHERTEXT 20 // NEW DE_LENGHT_KEY * 4
#define MAX_LEN_PLAINTEXT 19 // NEW DE_LENGHT_KEY * 4
#define DE_ERROR_NOERROR 1
#define DE_ERROR_KEYLENGHT_LONG -1
#define DE_ERROR_KEYLENGHT_SHORT -2
#define DE_ERROR_NOERROR 1
#define DE_ERROR_KEYLENGHT_LONG -1
#define DE_ERROR_KEYLENGHT_SHORT -2
private:
char _bufferCyphertext[MAX_LEN_CYPHERTEXT +1] = {0};
char _bufferPlaintext[MAX_LEN_PLAINTEXT +1] = {0};
char _key[DE_LENGHT_KEY +1] = {'0','0','0','0','0','0','0','0','\0'};
private:
char _bufferCyphertext[MAX_LEN_CYPHERTEXT + 1] = {0};
char _bufferPlaintext[MAX_LEN_PLAINTEXT + 1] = {0};
char _key[MAX_LEN_KEY + 1] = {'0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '\0'};
char _mark = '\0';
public:
public:
DidacticEncSymetric();
~DidacticEncSymetric();
int setKey(char*);
void crypt(char*, int, char*, char*, int);
void crypt(char*, char*, char*);
void crypt(char*, char*);
};
int setKey(char *);
void setTestMark(char);
void crypt(char *, int, char *, char *, int);
void crypt(char *, char *, char *);
void crypt(char *, char *);
void encrypt(char *, int, char *, char *, int, char);
void encrypt(char *, char *, char *, char);
void encrypt(char *, char *);
bool decrypt(char *, int, char *, char *, int, char);
bool decrypt(char *, char *, char *, char);
bool decrypt(char *, char *);
};
class DidacticEncAsymetric
class DidacticEncAsymetric
{
#define MAX_NR_OF_PRIMES 48
#define MAX_PRIME_OFFSET 3
#define MAX_LEN_PLAINTEXT 20
#define MAX_LEN_CYPHERTEXT 250
#define DE_CYPHER_SEPARATOR ";"
private:
const int prime[MAX_NR_OF_PRIMES] = { 17, 19, 23, 29, 31, 37,
41, 43, 47, 53, 59, 61, 67, 71, 73,
79, 83, 89, 97, 101, 103, 107, 109,
113, 127, 131, 137, 139, 149, 151, 157,
163, 167, 173, 179, 181, 191, 193, 197,
199, 211, 223, 227, 229, 233, 239, 241,
251};//, 257, 263, 269, 271, 277, 281};
char _bufferCyphertext[MAX_LEN_CYPHERTEXT +1] = {0};
#define MAX_NR_OF_PRIMES 48
#define MAX_PRIME_OFFSET 3
#define MAX_LEN_PLAINTEXT 20
#define MAX_LEN_CYPHERTEXT 250
#define DE_CYPHER_SEPARATOR ";"
private:
const int prime[MAX_NR_OF_PRIMES] = {17, 19, 23, 29, 31, 37,
41, 43, 47, 53, 59, 61, 67, 71, 73,
79, 83, 89, 97, 101, 103, 107, 109,
113, 127, 131, 137, 139, 149, 151, 157,
163, 167, 173, 179, 181, 191, 193, 197,
199, 211, 223, 227, 229, 233, 239, 241,
251}; //, 257, 263, 269, 271, 277, 281};
char _bufferCyphertext[MAX_LEN_CYPHERTEXT + 1] = {0};
long _privateKey = 0L;
long _publicKey = 0L;
long _rsaModule = 0L;
long _publicKey = 0L;
long _rsaModule = 0L;
int _randomPin = A5;
void generateRsaKeys(long, long, long&, long&, long&);
void generateRsaKeys(long, long, long &, long &, long &);
long cryptRsa(long key, long rsaModul, long message);
long getPrimeWithOffset(long);
long getPrime();
//rsa math functions
long gcd (long, long); //basic euclidean algorithm
long egcd (long, long, long&, long&); //extended euclidean algorithm
long modPow(long, long, long); //modular exponentation
// rsa math functions
long gcd(long, long); // basic euclidean algorithm
long egcd(long, long, long &, long &); // extended euclidean algorithm
long modPow(long, long, long); // modular exponentation
public:
public:
DidacticEncAsymetric();
~DidacticEncAsymetric();
......@@ -87,9 +96,9 @@ class DidacticEncAsymetric
long getPublicKey();
long getRsaModule();
int encrypt(char*, int, char*, long, long);
int encrypt(char*, char*, long, long);
int encrypt(char *, int, char *, long, long);
int encrypt(char *, char *, long, long);
int decrypt(char*, char*, long, long);
int decrypt(char *, char *, long, long);
};
#endif
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment