141 lines
5.8 KiB
Swift
141 lines
5.8 KiB
Swift
//
|
|
// Curve25519.swift
|
|
// Befund
|
|
//
|
|
// Created by Irakli Abetschkhrischwili on 29.04.22.
|
|
// Copyright © 2022 MVZ Dr. Stein und Kollegen. All rights reserved.
|
|
|
|
import Foundation
|
|
import CryptoKit
|
|
|
|
extension Core.Security
|
|
{
|
|
public struct Curve25519
|
|
{
|
|
/**
|
|
* Generates the KeyPair with Private & Public Keys
|
|
*
|
|
* @return returns KeyPair with Public & Private Keys(incl. Signing Private & Public Keys)
|
|
*/
|
|
static func GenerateKeyPair() -> KeyPair
|
|
{
|
|
let result: KeyPair = KeyPair()
|
|
|
|
let privateKey = CryptoKit.Curve25519.KeyAgreement.PrivateKey()
|
|
let publicKey = privateKey.publicKey
|
|
|
|
let signingPrivateKey = CryptoKit.Curve25519.Signing.PrivateKey()
|
|
let signingPublicKey = signingPrivateKey.publicKey
|
|
|
|
result.PrivateKey = privateKey.rawRepresentation.base64EncodedString()
|
|
result.PublicKey = publicKey.rawRepresentation.base64EncodedString()
|
|
|
|
result.SigningPrivateKey = signingPrivateKey.rawRepresentation.base64EncodedString()
|
|
result.SigningPublicKey = signingPublicKey.rawRepresentation.base64EncodedString()
|
|
|
|
return result
|
|
}
|
|
|
|
/*
|
|
* Creates KeyPair by private & public keys(base64 encoded)
|
|
*/
|
|
static func CreateKeyPair(_privateKey: String, _publicKey: String) -> KeyPair
|
|
{
|
|
let result: KeyPair = KeyPair()
|
|
|
|
let privateKey = try! CryptoKit.Curve25519.KeyAgreement.PrivateKey(rawRepresentation: Data(base64Encoded: _privateKey)!)
|
|
let publicKey = try! CryptoKit.Curve25519.KeyAgreement.PublicKey(rawRepresentation: Data(base64Encoded: _publicKey)!)
|
|
|
|
let signingPrivateKey = CryptoKit.Curve25519.Signing.PrivateKey()
|
|
let signingPublicKey = signingPrivateKey.publicKey
|
|
|
|
result.PrivateKey = privateKey.rawRepresentation.base64EncodedString()
|
|
result.PublicKey = publicKey.rawRepresentation.base64EncodedString()
|
|
result.SigningPrivateKey = signingPrivateKey.rawRepresentation.base64EncodedString()
|
|
result.SigningPublicKey = signingPublicKey.rawRepresentation.base64EncodedString()
|
|
|
|
return result
|
|
}
|
|
|
|
/**
|
|
* Validates a ED25519 Signature with message and public key of sender
|
|
*
|
|
* @param signature - signature that should be validated
|
|
* @param message - message that was signed
|
|
* @param publicKey - public key that was used by sender for the message to sign it
|
|
* @return returns true if valid
|
|
*/
|
|
static func CheckValid(signature: Data, message: Data, publicKey: Data) -> Bool
|
|
{
|
|
let key = try! CryptoKit.Curve25519.Signing.PublicKey(rawRepresentation: publicKey)
|
|
return key.isValidSignature(signature, for: message)
|
|
}
|
|
|
|
/**
|
|
* KeyPair with Private & Public Key and Signature Keys
|
|
*/
|
|
public class KeyPair
|
|
{
|
|
public var PrivateKey: String!
|
|
public var PublicKey: String!
|
|
public var SigningPublicKey: String!
|
|
public var SigningPrivateKey: String!
|
|
|
|
public func GetSignature(signingValue: String) -> String?
|
|
{
|
|
var result: String? = nil
|
|
|
|
do
|
|
{
|
|
let signingData = signingValue.data(using: .utf8)!
|
|
let privateKeyRaw: Data? = Data(base64Encoded: self.SigningPrivateKey!)
|
|
let privateKey = try! CryptoKit.Curve25519.Signing.PrivateKey(rawRepresentation: privateKeyRaw!)
|
|
result = try privateKey.signature(for: signingData).base64EncodedString()
|
|
}
|
|
catch
|
|
{
|
|
Core.Log.Error(err: error, namespace: "Core.Security.Curve25519.KeyPair", method: "GetSignature(String)")
|
|
}
|
|
|
|
return result
|
|
}
|
|
|
|
/**
|
|
* Returns a shared key with the public key
|
|
*
|
|
* @peerPublicKeyBase64 - Public key of peer in base64 string format
|
|
* @return returns shared key as byte array
|
|
*/
|
|
public func GetSharedKey(peerPublicKeyBase64: String?) -> CryptoKit.SymmetricKey?
|
|
{
|
|
var result: CryptoKit.SymmetricKey? = nil
|
|
|
|
if(peerPublicKeyBase64 != nil)
|
|
{
|
|
let privateKeyRaw: Data? = Data(base64Encoded: self.PrivateKey!)
|
|
|
|
if(privateKeyRaw != nil)
|
|
{
|
|
let privateKey = try! CryptoKit.Curve25519.KeyAgreement.PrivateKey(rawRepresentation: privateKeyRaw!)
|
|
|
|
let peerPublicKeyRaw: Data? = Data(base64Encoded: peerPublicKeyBase64!)
|
|
|
|
if(peerPublicKeyRaw != nil)
|
|
{
|
|
let peerPublicKey = try! CryptoKit.Curve25519.KeyAgreement.PublicKey(rawRepresentation: peerPublicKeyRaw!)
|
|
|
|
let sharedSecret = try! privateKey.sharedSecretFromKeyAgreement(with: peerPublicKey)
|
|
|
|
let protocolSalt = ""
|
|
|
|
result = sharedSecret.hkdfDerivedSymmetricKey(using: CryptoKit.SHA512.self, salt: protocolSalt.data(using: .ascii)!, sharedInfo: Data(), outputByteCount: 32)
|
|
}
|
|
}
|
|
}
|
|
|
|
return result
|
|
}
|
|
}
|
|
}
|
|
}
|