started darkID

This commit is contained in:
arnaucode
2017-12-28 18:20:11 +01:00
parent 90276423c0
commit 5a3d2a5944
56 changed files with 2163 additions and 0 deletions

5
serverIDsigner/README.md Normal file
View File

@@ -0,0 +1,5 @@
# serverIDsign
- The server where the user creates a non anonymous account
- Also is the server that blind signs the Anonymous ID of the users
- Have the webapp (frontend) to interact through a GUI interface

8
serverIDsigner/config.json Executable file
View File

@@ -0,0 +1,8 @@
{
"ip": "127.0.0.1",
"port": "3130",
"mongodb": {
"ip": "127.0.0.1:27017",
"database": "serverIDsigner"
}
}

15
serverIDsigner/errors.go Executable file
View File

@@ -0,0 +1,15 @@
package main
import (
"log"
"runtime"
)
func check(err error) {
if err != nil {
_, fn, line, _ := runtime.Caller(1)
log.Println(line)
log.Println(fn)
log.Println(err)
}
}

24
serverIDsigner/log.go Executable file
View File

@@ -0,0 +1,24 @@
package main
import (
"io"
"log"
"os"
"strings"
"time"
)
func savelog() {
timeS := time.Now().String()
_ = os.Mkdir("logs", os.ModePerm)
//next 3 lines are to avoid windows filesystem errors
timeS = strings.Replace(timeS, " ", "_", -1)
timeS = strings.Replace(timeS, ".", "-", -1)
timeS = strings.Replace(timeS, ":", "-", -1)
logFile, err := os.OpenFile("logs/log-"+timeS+".log", os.O_CREATE|os.O_APPEND|os.O_RDWR, 0666)
if err != nil {
panic(err)
}
mw := io.MultiWriter(os.Stdout, logFile)
log.SetOutput(mw)
}

49
serverIDsigner/main.go Normal file
View File

@@ -0,0 +1,49 @@
package main
import (
"fmt"
"log"
"net/http"
mgo "gopkg.in/mgo.v2"
"github.com/fatih/color"
"github.com/gorilla/handlers"
ownrsa "./ownrsa"
)
var userCollection *mgo.Collection
var serverRSA ownrsa.RSA
func main() {
color.Blue("Starting serverIDsigner")
//read configuration file
readConfig("config.json")
initializeToken()
//initialize RSA
serverRSA = ownrsa.GenerateKeyPair()
color.Blue("Public Key:")
fmt.Println(serverRSA.PubK)
color.Green("Private Key:")
fmt.Println(serverRSA.PrivK)
//mongodb
session, err := getSession()
check(err)
userCollection = getCollection(session, "users")
//run API
log.Println("api server running")
log.Print("port: ")
log.Println(config.Port)
router := NewRouter()
headersOk := handlers.AllowedHeaders([]string{"X-Requested-With", "Access-Control-Allow-Origin"})
originsOk := handlers.AllowedOrigins([]string{"*"})
methodsOk := handlers.AllowedMethods([]string{"GET", "HEAD", "POST", "PUT", "OPTIONS"})
log.Fatal(http.ListenAndServe(":"+config.Port, handlers.CORS(originsOk, headersOk, methodsOk)(router)))
}

View File

@@ -0,0 +1,26 @@
package main
import (
mgo "gopkg.in/mgo.v2"
)
func getSession() (*mgo.Session, error) {
session, err := mgo.Dial("mongodb://" + config.Mongodb.IP)
if err != nil {
panic(err)
}
//defer session.Close()
// Optional. Switch the session to a monotonic behavior.
session.SetMode(mgo.Monotonic, true)
// Optional. Switch the session to a monotonic behavior.
session.SetMode(mgo.Monotonic, true)
return session, err
}
func getCollection(session *mgo.Session, collection string) *mgo.Collection {
c := session.DB(config.Mongodb.Database).C(collection)
return c
}

View File

@@ -0,0 +1,54 @@
package ownrsa
import "math/rand"
func randInt(min int, max int) int {
r := rand.Intn(max-min) + min
return r
}
func randPrime(min int, max int) int {
primes := sieveOfEratosthenes(max)
randN := rand.Intn(len(primes)-0) + 0
return primes[randN]
}
// return list of primes less than N
func sieveOfEratosthenes(N int) (primes []int) {
b := make([]bool, N)
for i := 2; i < N; i++ {
if b[i] == true {
continue
}
primes = append(primes, i)
for k := i * i; k < N; k += i {
b[k] = true
}
}
return
}
func gcd(a, b int) int {
var bgcd func(a, b, res int) int
bgcd = func(a, b, res int) int {
switch {
case a == b:
return res * a
case a%2 == 0 && b%2 == 0:
return bgcd(a/2, b/2, 2*res)
case a%2 == 0:
return bgcd(a/2, b, res)
case b%2 == 0:
return bgcd(a, b/2, res)
case a > b:
return bgcd(a-b, b, res)
default:
return bgcd(a, b-a, res)
}
}
return bgcd(a, b, 1)
}

View File

@@ -0,0 +1,228 @@
package ownrsa
import (
"errors"
"fmt"
"math/big"
"math/rand"
"strconv"
"strings"
"time"
)
type RSAPublicKey struct {
E *big.Int `json:"e"`
N *big.Int `json:"n"`
}
type RSAPublicKeyString struct {
E string `json:"e"`
N string `json:"n"`
}
type RSAPrivateKey struct {
D *big.Int `json:"d"`
N *big.Int `json:"n"`
}
type RSA struct {
PubK RSAPublicKey
PrivK RSAPrivateKey
}
type PackRSA struct {
PubK string `json:"pubK"`
PrivK string `json:"privK"`
Date time.Time `json:"date"`
PubKSigned string `json:"pubKSigned"`
}
const maxPrime = 500
const minPrime = 100
func GenerateKeyPair() RSA {
rand.Seed(time.Now().Unix())
p := randPrime(minPrime, maxPrime)
q := randPrime(minPrime, maxPrime)
fmt.Print("p:")
fmt.Println(p)
fmt.Print("q:")
fmt.Println(q)
n := p * q
phi := (p - 1) * (q - 1)
e := 65537
var pubK RSAPublicKey
pubK.E = big.NewInt(int64(e))
pubK.N = big.NewInt(int64(n))
d := new(big.Int).ModInverse(big.NewInt(int64(e)), big.NewInt(int64(phi)))
var privK RSAPrivateKey
privK.D = d
privK.N = big.NewInt(int64(n))
var rsa RSA
rsa.PubK = pubK
rsa.PrivK = privK
return rsa
}
func Encrypt(m string, pubK RSAPublicKey) []int {
var c []int
mBytes := []byte(m)
for _, byte := range mBytes {
c = append(c, EncryptInt(int(byte), pubK))
}
return c
}
func Decrypt(c []int, privK RSAPrivateKey) string {
var m string
var mBytes []byte
for _, indC := range c {
mBytes = append(mBytes, byte(DecryptInt(indC, privK)))
}
m = string(mBytes)
return m
}
func EncryptBigInt(bigint *big.Int, pubK RSAPublicKey) *big.Int {
Me := new(big.Int).Exp(bigint, pubK.E, nil)
c := new(big.Int).Mod(Me, pubK.N)
return c
}
func DecryptBigInt(bigint *big.Int, privK RSAPrivateKey) *big.Int {
Cd := new(big.Int).Exp(bigint, privK.D, nil)
m := new(big.Int).Mod(Cd, privK.N)
return m
}
func EncryptInt(char int, pubK RSAPublicKey) int {
charBig := big.NewInt(int64(char))
Me := charBig.Exp(charBig, pubK.E, nil)
c := Me.Mod(Me, pubK.N)
return int(c.Int64())
}
func DecryptInt(val int, privK RSAPrivateKey) int {
valBig := big.NewInt(int64(val))
Cd := valBig.Exp(valBig, privK.D, nil)
m := Cd.Mod(Cd, privK.N)
return int(m.Int64())
}
func Blind(m []int, r int, pubK RSAPublicKey, privK RSAPrivateKey) []int {
var mBlinded []int
rBigInt := big.NewInt(int64(r))
for i := 0; i < len(m); i++ {
mBigInt := big.NewInt(int64(m[i]))
rE := new(big.Int).Exp(rBigInt, pubK.E, nil)
mrE := new(big.Int).Mul(mBigInt, rE)
mrEmodN := new(big.Int).Mod(mrE, privK.N)
mBlinded = append(mBlinded, int(mrEmodN.Int64()))
}
return mBlinded
}
func BlindSign(m []int, privK RSAPrivateKey) []int {
var r []int
for i := 0; i < len(m); i++ {
mBigInt := big.NewInt(int64(m[i]))
sigma := new(big.Int).Exp(mBigInt, privK.D, privK.N)
r = append(r, int(sigma.Int64()))
}
return r
}
func Unblind(blindsigned []int, r int, pubK RSAPublicKey) []int {
var mSigned []int
rBigInt := big.NewInt(int64(r))
for i := 0; i < len(blindsigned); i++ {
bsBigInt := big.NewInt(int64(blindsigned[i]))
//r1 := new(big.Int).Exp(rBigInt, big.NewInt(int64(-1)), nil)
r1 := new(big.Int).ModInverse(rBigInt, pubK.N)
bsr := new(big.Int).Mul(bsBigInt, r1)
sig := new(big.Int).Mod(bsr, pubK.N)
mSigned = append(mSigned, int(sig.Int64()))
}
return mSigned
}
func Verify(msg []int, mSigned []int, pubK RSAPublicKey) bool {
if len(msg) != len(mSigned) {
return false
}
var mSignedDecrypted []int
for _, ms := range mSigned {
msBig := big.NewInt(int64(ms))
//decrypt the mSigned with pubK
Cd := new(big.Int).Exp(msBig, pubK.E, nil)
m := new(big.Int).Mod(Cd, pubK.N)
mSignedDecrypted = append(mSignedDecrypted, int(m.Int64()))
}
fmt.Print("msg signed decrypted: ")
fmt.Println(mSignedDecrypted)
r := true
//check if the mSignedDecrypted == msg
for i := 0; i < len(msg); i++ {
if msg[i] != mSignedDecrypted[i] {
r = false
}
}
return r
}
func HomomorphicMultiplication(c1 int, c2 int, pubK RSAPublicKey) int {
c1BigInt := big.NewInt(int64(c1))
c2BigInt := big.NewInt(int64(c2))
c1c2 := new(big.Int).Mul(c1BigInt, c2BigInt)
n2 := new(big.Int).Mul(pubK.N, pubK.N)
d := new(big.Int).Mod(c1c2, n2)
r := int(d.Int64())
return r
}
func PubKStringToBigInt(kS RSAPublicKeyString) (RSAPublicKey, error) {
var k RSAPublicKey
var ok bool
k.E, ok = new(big.Int).SetString(kS.E, 10)
if !ok {
return k, errors.New("error parsing big int E")
}
k.N, ok = new(big.Int).SetString(kS.N, 10)
if !ok {
return k, errors.New("error parsing big int N")
}
return k, nil
}
func PackKey(k RSA) PackRSA {
var p PackRSA
p.PubK = k.PubK.E.String() + "," + k.PubK.N.String()
p.PrivK = k.PrivK.D.String() + "," + k.PrivK.N.String()
return p
}
func UnpackKey(p PackRSA) RSA {
var k RSA
var ok bool
k.PubK.E, ok = new(big.Int).SetString(strings.Split(p.PubK, ",")[0], 10)
k.PubK.N, ok = new(big.Int).SetString(strings.Split(p.PubK, ",")[1], 10)
k.PrivK.D, ok = new(big.Int).SetString(strings.Split(p.PrivK, ",")[0], 10)
k.PrivK.N, ok = new(big.Int).SetString(strings.Split(p.PrivK, ",")[1], 10)
if !ok {
fmt.Println("error on Unpacking Keys")
}
return k
}
func ArrayIntToString(a []int, delim string) string {
return strings.Trim(strings.Replace(fmt.Sprint(a), " ", delim, -1), "[]")
}
func StringToArrayInt(s string, delim string) []int {
var a []int
arrayString := strings.Split(s, delim)
for _, s := range arrayString {
i, err := strconv.Atoi(s)
if err != nil {
fmt.Println(err)
}
a = append(a, i)
}
return a
}

26
serverIDsigner/readConfig.go Executable file
View File

@@ -0,0 +1,26 @@
package main
import (
"encoding/json"
"io/ioutil"
)
//Config reads the config
type Config struct {
IP string `json:"ip"`
Port string `json:"port"`
Mongodb MongoConfig `json:"mongodb"`
}
type MongoConfig struct {
IP string `json:"ip"`
Database string `json:"database"`
}
var config Config
func readConfig(path string) {
file, err := ioutil.ReadFile(path)
check(err)
content := string(file)
json.Unmarshal([]byte(content), &config)
}

47
serverIDsigner/restConfig.go Executable file
View File

@@ -0,0 +1,47 @@
package main
import (
"log"
"net/http"
"time"
"github.com/gorilla/mux"
)
type Route struct {
Name string
Method string
Pattern string
HandlerFunc http.HandlerFunc
}
func Logger(inner http.Handler, name string) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
inner.ServeHTTP(w, r)
log.Printf(
"%s\t%s\t%s\t%s",
r.Method,
r.RequestURI,
name,
time.Since(start),
)
})
}
func NewRouter() *mux.Router {
router := mux.NewRouter().StrictSlash(true)
for _, route := range routes {
var handler http.Handler
handler = route.HandlerFunc
handler = Logger(handler, route.Name)
router.
Methods(route.Method).
Path(route.Pattern).
Name(route.Name).
Handler(handler)
}
return router
}

36
serverIDsigner/restRoutes.go Executable file
View File

@@ -0,0 +1,36 @@
package main
type Routes []Route
var routes = Routes{
Route{
"Index",
"GET",
"/",
Index,
},
Route{
"Signup",
"POST",
"/signup",
Signup,
},
Route{
"Login",
"POST",
"/login",
Login,
},
Route{
"BlindSign",
"POST",
"/blindsign",
BlindSign,
},
Route{
"VerifySign",
"POST",
"/verifysign",
VerifySign,
},
}

View File

@@ -0,0 +1,20 @@
echo ""
echo "sending the signup, response:"
curl -X POST http://127.0.0.1:3130/signup -d '{"email": "user1@e.com", "password": "user1"}'
echo ""
echo "sending the login, response:"
curl -X POST http://127.0.0.1:3130/login -d '{"email": "user1@e.com", "password": "user1"}'
echo ""
echo "send pubK and m to blind sign"
echo "json to send to the serverIDsigner:"
echo '{"m": "hola"}'
echo "serverIDsigner response:"
BLINDSIGNED=$(curl -X POST http://127.0.0.1:3130/blindsign -d '{"m": "hola"}')
echo "$BLINDSIGNED"
echo ""
echo "send blindsigned to the serverIDsigner to verify"
curl -X POST http://127.0.0.1:3130/verifysign -d '{"m": "hola", "mSigned": "131898 40373 107552 34687"}'

49
serverIDsigner/tokens.go Normal file
View File

@@ -0,0 +1,49 @@
package main
import (
"fmt"
"time"
jwt "github.com/dgrijalva/jwt-go"
)
const (
signingKey = "this is the secret signing key"
)
var createdToken string
func initializeToken() {
var err error
createdToken, err = newToken()
if err != nil {
fmt.Println("Creating token failed")
}
}
func newToken() (string, error) {
signingKeyB := []byte(signingKey)
// Create the token
token := jwt.New(jwt.SigningMethodHS256)
// Set some claims
claims := make(jwt.MapClaims)
claims["foo"] = "bar"
claims["exp"] = time.Now().Add(time.Hour * 72).Unix()
token.Claims = claims
// Sign and get the complete encoded token as a string
tokenString, err := token.SignedString(signingKeyB)
return tokenString, err
}
func parseToken(myToken string, myKey string) {
token, err := jwt.Parse(myToken, func(token *jwt.Token) (interface{}, error) {
return []byte(myKey), nil
})
if err == nil && token.Valid {
fmt.Println("Your token is valid. I like your style.")
} else {
fmt.Println("This token is terrible! I cannot accept this.")
}
}

View File

@@ -0,0 +1,186 @@
package main
import (
"encoding/json"
"fmt"
"net/http"
"strconv"
"strings"
"github.com/fatih/color"
"gopkg.in/mgo.v2/bson"
ownrsa "./ownrsa"
)
type User struct {
Id bson.ObjectId `json:"id" bson:"_id,omitempty"`
Email string `json:"email"`
Password string `json:"password"`
Token string `json:"token"`
}
func Index(w http.ResponseWriter, r *http.Request) {
//TODO return the public key, to allow others verifign signed strings by this server
jResp, err := json.Marshal(serverRSA.PubK)
if err != nil {
panic(err)
}
fmt.Fprintln(w, string(jResp))
}
func Signup(w http.ResponseWriter, r *http.Request) {
decoder := json.NewDecoder(r.Body)
var user User
err := decoder.Decode(&user)
if err != nil {
panic(err)
}
defer r.Body.Close()
fmt.Print("user signup: ")
fmt.Println(user)
//save the new project to mongodb
rUser := User{}
err = userCollection.Find(bson.M{"email": user.Email}).One(&rUser)
if err != nil {
//user not exists
err = userCollection.Insert(user) //TODO find a way to get the object result when inserting in one line, without need of the two mgo petitions
err = userCollection.Find(bson.M{"email": user.Email}).One(&user)
} else {
//user exists
fmt.Fprintln(w, "User already registered")
return
}
jResp, err := json.Marshal(user)
if err != nil {
panic(err)
}
fmt.Fprintln(w, string(jResp))
}
func Login(w http.ResponseWriter, r *http.Request) {
decoder := json.NewDecoder(r.Body)
var user User
err := decoder.Decode(&user)
if err != nil {
panic(err)
}
defer r.Body.Close()
//TODO check if the user password exists in the database
fmt.Print("user login: ")
fmt.Println(user)
token, err := newToken()
check(err)
user.Token = token
//save the new project to mongodb
rUser := User{}
err = userCollection.Find(bson.M{"email": user.Email}).One(&rUser)
if err != nil {
} else {
//user exists, update with the token
err = userCollection.Update(bson.M{"_id": rUser.Id}, user)
check(err)
}
jResp, err := json.Marshal(user)
if err != nil {
panic(err)
}
fmt.Fprintln(w, string(jResp))
}
type Sign struct {
M string `json:"m"`
C string `json:"c"`
}
type AskBlindSign struct {
/*PubKString ownrsa.RSAPublicKeyString `json:"pubKstring"`
PubK ownrsa.RSAPublicKey `json:"pubK"`*/
M string `json:"m"`
}
func BlindSign(w http.ResponseWriter, r *http.Request) {
decoder := json.NewDecoder(r.Body)
var askBlindSign AskBlindSign
err := decoder.Decode(&askBlindSign)
if err != nil {
panic(err)
}
defer r.Body.Close()
color.Red(askBlindSign.M)
fmt.Println(askBlindSign)
/*fmt.Println(askBlindSign)
askBlindSign.PubK, err = ownrsa.PubKStringToBigInt(askBlindSign.PubKString)
if err != nil {
fmt.Fprintln(w, "error")
return
}*/
//convert msg to []int
/*var m []int
mBytes := []byte(askBlindSign.M)
for _, byte := range mBytes {
m = append(m, int(byte))
}*/
m := ownrsa.StringToArrayInt(askBlindSign.M, "_")
sigma := ownrsa.BlindSign(m, serverRSA.PrivK) //here the privK will be the CA privK, not the m emmiter's one. The pubK is the user's one
fmt.Print("Sigma': ")
fmt.Println(sigma)
sigmaString := ownrsa.ArrayIntToString(sigma, "_")
askBlindSign.M = sigmaString
jResp, err := json.Marshal(askBlindSign)
if err != nil {
panic(err)
}
fmt.Fprintln(w, string(jResp))
}
type PetitionVerifySign struct {
M string `json:"m"`
MSigned string `json:"mSigned"`
}
func VerifySign(w http.ResponseWriter, r *http.Request) {
decoder := json.NewDecoder(r.Body)
var petitionVerifySign PetitionVerifySign
err := decoder.Decode(&petitionVerifySign)
if err != nil {
panic(err)
}
defer r.Body.Close()
fmt.Println(petitionVerifySign)
//convert M to []int
var mOriginal []int
mBytes := []byte(petitionVerifySign.M)
for _, byte := range mBytes {
mOriginal = append(mOriginal, int(byte))
}
//convert MSigned to []int
var mSignedInts []int
mSignedString := strings.Split(petitionVerifySign.MSigned, " ")
for _, s := range mSignedString {
i, err := strconv.Atoi(s)
check(err)
mSignedInts = append(mSignedInts, i)
}
verified := ownrsa.Verify(mOriginal, mSignedInts, serverRSA.PubK)
fmt.Fprintln(w, verified)
}