Created
December 26, 2016 18:56
-
-
Save lnlonSA/d8933a2c57a417ec1b3e56b573117a7d to your computer and use it in GitHub Desktop.
مشروع أمن نظم المعلومات
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* To change this license header, choose License Headers in Project Properties. | |
* To change this template file, choose Tools | Templates | |
* and open the template in the editor. | |
*/ | |
package bitcion; | |
import java.io.IOException; | |
import java.io.InputStream; | |
import java.io.ObjectInputStream; | |
import java.io.ObjectOutputStream; | |
import java.io.OutputStream; | |
import java.io.Serializable; | |
import java.security.*; | |
import java.security.spec.InvalidKeySpecException; | |
import javax.crypto.*; | |
import javax.crypto.spec.IvParameterSpec; | |
import javax.crypto.spec.SecretKeySpec; | |
import sun.misc.*; | |
/** | |
* | |
* @author LaNa Sa | |
*/ | |
public class AES { | |
private static final byte[] key = "MyDifficultPassw".getBytes(); | |
private static final String transformation = "AES/ECB/PKCS5Padding"; | |
public static SealedObject encrypt(Serializable object,byte[] key) throws IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException { | |
try { | |
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); | |
MessageDigest digest = MessageDigest.getInstance("SHA-256"); | |
final byte[] reallyHashed = digest.digest(key); | |
SecretKeySpec sks = new SecretKeySpec(reallyHashed, "AES"); | |
cipher.init(Cipher.ENCRYPT_MODE, sks); | |
SealedObject sealedObject = new SealedObject(object, cipher); | |
return sealedObject; | |
} catch (IllegalBlockSizeException e) { | |
e.printStackTrace(); | |
return null; | |
} | |
} | |
public static Object decrypt(SealedObject enc_data,byte[] key) throws IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException { | |
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); | |
MessageDigest digest = MessageDigest.getInstance("SHA-256"); | |
final byte[] reallyHashed = digest.digest(key); | |
SecretKeySpec sks = new SecretKeySpec(reallyHashed, "AES"); | |
cipher.init(Cipher.DECRYPT_MODE, sks); | |
try { | |
return enc_data.getObject(cipher); | |
} catch (ClassNotFoundException | IllegalBlockSizeException | BadPaddingException e) { | |
e.printStackTrace(); | |
return null; | |
} | |
} | |
} | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* To change this license header, choose License Headers in Project Properties. | |
* To change this template file, choose Tools | Templates | |
* and open the template in the editor. | |
*/ | |
package bitcion; | |
import java.security.Key; | |
import javax.crypto.Cipher; | |
import javax.crypto.spec.SecretKeySpec; | |
import sun.misc.BASE64Decoder; | |
import sun.misc.BASE64Encoder; | |
/** | |
* | |
* @author LaNa Sa | |
*/ | |
public class AESstringEncrypt { | |
private static final String ALGO = "AES"; | |
public static String encrypt(String Data,byte[] passPhrase) throws Exception { | |
Key key = generateKey(passPhrase); | |
Cipher c = Cipher.getInstance(ALGO); | |
c.init(Cipher.ENCRYPT_MODE, key); | |
byte[] encVal = c.doFinal(Data.getBytes()); | |
String encryptedValue = new BASE64Encoder().encode(encVal); | |
return encryptedValue; | |
} | |
public static String decrypt(String encryptedData,byte[] passPhrase) throws Exception { | |
Key key = generateKey(passPhrase); | |
Cipher c = Cipher.getInstance(ALGO); | |
c.init(Cipher.DECRYPT_MODE, key); | |
byte[] decordedValue = new BASE64Decoder().decodeBuffer(encryptedData); | |
byte[] decValue = c.doFinal(decordedValue); | |
String decryptedValue = new String(decValue); | |
return decryptedValue; | |
} | |
private static Key generateKey(byte[] passPhrase) throws Exception { | |
Key key = new SecretKeySpec(passPhrase, ALGO); | |
return key; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* To change this license header, choose License Headers in Project Properties. | |
* To change this template file, choose Tools | Templates | |
* and open the template in the editor. | |
*/ | |
package bitcion; | |
import java.io.Serializable; | |
import java.security.PrivateKey; | |
import java.security.PublicKey; | |
/** | |
* | |
* @author LaNa Sa | |
*/ | |
public class CertificateRequest implements Serializable{ | |
private String SubjectName; | |
private PublicKey subjectPublicKey; | |
private byte[] signature; | |
public static CertificateRequest create(String subjectName,PublicKey subjectPublicKey,PrivateKey clientPrivateKey) | |
{ | |
CertificateRequest CRS = new CertificateRequest(); | |
CRS.SubjectName = subjectName; | |
CRS.subjectPublicKey = subjectPublicKey; | |
byte[] crsInfo = CRS.concat(CRS.SubjectName.getBytes(),CRS.subjectPublicKey.getEncoded()); | |
CRS.findSignature(crsInfo, clientPrivateKey); | |
return CRS; | |
} | |
private void findSignature(byte[] cer,PrivateKey CAPrivateKey) | |
{ | |
//concate certificate fildes for find signature: | |
signature = GenerateSignature.generate(cer, CAPrivateKey); | |
} | |
public byte[] concat(byte[]...arrays) | |
{ | |
// Determine the length of the result array | |
int totalLength = 0; | |
for (int i = 0; i < arrays.length; i++) | |
{ | |
totalLength += arrays[i].length; | |
} | |
// create the result array | |
byte[] result = new byte[totalLength]; | |
// copy the source arrays into the result array | |
int currentIndex = 0; | |
for (int i = 0; i < arrays.length; i++) | |
{ | |
System.arraycopy(arrays[i], 0, result, currentIndex, arrays[i].length); | |
currentIndex += arrays[i].length; | |
} | |
return result; | |
} | |
public String getSubjectName() { | |
return SubjectName; | |
} | |
public PublicKey getSubjectPublicKey() { | |
return subjectPublicKey; | |
} | |
public byte[] getSignature() { | |
return signature; | |
} | |
public boolean Verify() | |
{ | |
byte[] crsInfo = this.concat(this.SubjectName.getBytes(),this.subjectPublicKey.getEncoded()); | |
return VerficationSignature.verify(crsInfo, signature, this.subjectPublicKey); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* To change this license header, choose License Headers in Project Properties. | |
* To change this template file, choose Tools | Templates | |
* and open the template in the editor. | |
*/ | |
package bitcion; | |
import java.io.BufferedOutputStream; | |
import java.io.BufferedReader; | |
import java.io.DataInputStream; | |
import java.io.DataOutputStream; | |
import java.io.FileNotFoundException; | |
import java.io.FileReader; | |
import java.io.IOException; | |
import java.io.InputStream; | |
import java.io.ObjectInputStream; | |
import java.io.ObjectOutputStream; | |
import java.io.OutputStream; | |
import java.io.PrintWriter; | |
import java.net.Socket; | |
import java.security.InvalidKeyException; | |
import java.security.Key; | |
import java.security.KeyFactory; | |
import java.security.KeyPair; | |
import java.security.KeyPairGenerator; | |
import java.security.NoSuchAlgorithmException; | |
import java.security.PrivateKey; | |
import java.security.PublicKey; | |
import java.security.spec.InvalidKeySpecException; | |
import java.security.spec.PKCS8EncodedKeySpec; | |
import java.security.spec.X509EncodedKeySpec; | |
import java.util.ArrayList; | |
import java.util.Base64; | |
import java.util.List; | |
import java.util.logging.Level; | |
import java.util.logging.Logger; | |
import javax.crypto.BadPaddingException; | |
import javax.crypto.IllegalBlockSizeException; | |
import javax.crypto.NoSuchPaddingException; | |
import javax.crypto.SealedObject; | |
import sun.misc.BASE64Decoder; | |
import sun.misc.BASE64Encoder; | |
/** | |
* | |
* @author LaNa Sa | |
*/ | |
public class ClientClass { | |
public static KeyPair readKeyPair() throws FileNotFoundException | |
{ | |
BufferedReader br; | |
try { | |
br = new BufferedReader(new FileReader("publicKey.txt")); | |
StringBuilder sb = new StringBuilder(); | |
String line = br.readLine(); | |
while (line != null) { | |
sb.append(line); | |
sb.append(System.lineSeparator()); | |
line = br.readLine(); | |
} | |
String publicK = sb.toString(); | |
//convert public key from String to PublicKey: | |
byte[] publicBytes = new BASE64Decoder().decodeBuffer(publicK); | |
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicBytes); | |
KeyFactory keyFactory = KeyFactory.getInstance("RSA"); | |
PublicKey pubKey = keyFactory.generatePublic(keySpec); | |
br.close(); | |
br = new BufferedReader(new FileReader("privateKey.txt")); | |
sb = new StringBuilder(); | |
line = br.readLine(); | |
while (line != null) { | |
sb.append(line); | |
sb.append(System.lineSeparator()); | |
line = br.readLine(); | |
} | |
String privateK = sb.toString(); | |
//convert private key from String to PublicKey: | |
byte[] privateBytes = new BASE64Decoder().decodeBuffer(privateK); | |
PKCS8EncodedKeySpec keySpec2 = new PKCS8EncodedKeySpec(privateBytes); | |
PrivateKey privKey = keyFactory.generatePrivate(keySpec2); | |
br.close(); | |
//genrate keyPair: | |
return new KeyPair(pubKey, privKey); | |
} catch (IOException ex) { | |
Logger.getLogger(ClientClass.class.getName()).log(Level.SEVERE, null, ex); | |
return null; | |
} catch (NoSuchAlgorithmException ex) { | |
Logger.getLogger(ClientClass.class.getName()).log(Level.SEVERE, null, ex); | |
return null; | |
} catch (InvalidKeySpecException ex) { | |
Logger.getLogger(ClientClass.class.getName()).log(Level.SEVERE, null, ex); | |
return null; | |
} | |
} | |
public static void generateAndStoreKeys() | |
{ | |
try{ | |
//generate keypair for CA: | |
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA"); | |
keyPairGen.initialize(2048); | |
KeyPair keyPair = keyPairGen.genKeyPair(); | |
PublicKey publicKey = keyPair.getPublic(); | |
PrivateKey privateKey = keyPair.getPrivate(); | |
//convert keys to string fpr store them: | |
String publicK = new BASE64Encoder().encode(publicKey.getEncoded()); | |
String privateK = new BASE64Encoder().encode(privateKey.getEncoded()); | |
//store public key: | |
PrintWriter writer = new PrintWriter("publicKey.txt"); | |
writer.println(publicK); | |
writer.close(); | |
//store encrypted privateKey: | |
writer = new PrintWriter("privateKey.txt"); | |
writer.println(privateK); | |
writer.close(); | |
} catch (IOException e) { | |
// do something | |
} catch (Exception ex) { | |
Logger.getLogger(CertificateAuthority.class.getName()).log(Level.SEVERE, null, ex); | |
} | |
} | |
public static void main(String[] argc) throws FileNotFoundException | |
{ | |
String server_name="localhost"; | |
int port_number=1234; | |
KeyPair myPair = null; | |
// Get my KeyPair from file: | |
myPair = readKeyPair(); | |
System.out.println("Connecting to "+server_name+" on port "+port_number); | |
try { | |
Socket client = new Socket(server_name,port_number); | |
System.out.println(client.getRemoteSocketAddress()); | |
ObjectOutputStream out = new ObjectOutputStream(client.getOutputStream()); | |
ObjectInputStream in = new ObjectInputStream(client.getInputStream()); | |
//generate certificaterequest: | |
CertificateRequest crs = CertificateRequest.create("192.168.1.116",myPair.getPublic(), myPair.getPrivate()); | |
//send Request to CA: | |
out.writeObject(crs); | |
out.flush(); | |
//recv Certificate from CA: | |
DigitalCertificate cer = (DigitalCertificate) in.readObject(); | |
//view certificate: | |
System.out.println(cer.toString()); | |
//finish and close the socket: | |
client.close(); | |
//open socket with system server: | |
port_number=6000; | |
System.out.println("Connecting to "+server_name+" on port "+port_number); | |
client = new Socket(server_name,port_number); | |
System.out.println(client.getRemoteSocketAddress()); | |
out = new ObjectOutputStream(client.getOutputStream()); | |
in = new ObjectInputStream(client.getInputStream()); | |
//send signup request to server: | |
out.writeObject(new String("signUp")); | |
out.flush(); | |
//send my certificate to server: | |
out.writeObject(cer); | |
//finish and close the socket: | |
client.close(); | |
} catch (IOException ex) { | |
Logger.getLogger(ClientClass.class.getName()).log(Level.SEVERE, null, ex); | |
} catch (ClassNotFoundException ex) { | |
Logger.getLogger(ClientClass.class.getName()).log(Level.SEVERE, null, ex); | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* To change this license header, choose License Headers in Project Properties. | |
* To change this template file, choose Tools | Templates | |
* and open the template in the editor. | |
*/ | |
package bitcion; | |
import java.io.Serializable; | |
import java.security.PrivateKey; | |
import java.security.PublicKey; | |
import java.util.Calendar; | |
import java.util.Date; | |
import java.util.GregorianCalendar; | |
import sun.misc.BASE64Encoder; | |
/** | |
* | |
* @author LaNa Sa | |
*/ | |
public class DigitalCertificate implements Serializable{ | |
private int serialNumber; | |
private String issuerName; | |
private Date IssuingDate; | |
private Date validityFinishDate; | |
private int validity; | |
private String subjectName; | |
private PublicKey subjectPublicKey; | |
private byte[] signature; | |
public static DigitalCertificate createCer(int serialNumber,String issuerName,String subjectName | |
,PublicKey subjectPublicKey,int validity,PrivateKey CAPrivateKey) | |
{ | |
DigitalCertificate cer = new DigitalCertificate(); | |
cer.serialNumber = serialNumber; | |
cer.issuerName = issuerName; | |
cer.validity = validity; | |
cer.findDates(); | |
cer.subjectName = subjectName; | |
cer.subjectPublicKey = subjectPublicKey; | |
cer.findSignature(cer.cerToByte(), CAPrivateKey); | |
return cer; | |
} | |
private void findDates() | |
{ | |
//issuing date is the current date: | |
IssuingDate = new Date(); | |
//validity finish date is the issuaing date + validity days: | |
Calendar c= new GregorianCalendar(); | |
c.add(Calendar.DATE, validity); | |
validityFinishDate = c.getTime(); | |
} | |
private void findSignature(byte[] cer,PrivateKey CAPrivateKey) | |
{ | |
//concate certificate fildes for find signature: | |
signature = GenerateSignature.generate(cer, CAPrivateKey); | |
} | |
public byte[] cerToByte() | |
{ | |
return concat( Integer.toString(serialNumber).getBytes(), | |
issuerName.getBytes(), | |
IssuingDate.toString().getBytes(), | |
validityFinishDate.toString().getBytes(), | |
subjectName.getBytes(), | |
subjectPublicKey.getEncoded() | |
) ; | |
} | |
public byte[] concat(byte[]...arrays) | |
{ | |
// Determine the length of the result array | |
int totalLength = 0; | |
for (int i = 0; i < arrays.length; i++) | |
{ | |
totalLength += arrays[i].length; | |
} | |
// create the result array | |
byte[] result = new byte[totalLength]; | |
// copy the source arrays into the result array | |
int currentIndex = 0; | |
for (int i = 0; i < arrays.length; i++) | |
{ | |
System.arraycopy(arrays[i], 0, result, currentIndex, arrays[i].length); | |
currentIndex += arrays[i].length; | |
} | |
return result; | |
} | |
@Override | |
public String toString() { | |
//convert keys to string fpr store them: | |
String publicK = new BASE64Encoder().encode(subjectPublicKey.getEncoded()); | |
return "DigitalCertificate:" + "\nserialNumber=" + serialNumber + "\nissuerName=" + issuerName + "\nIssuingDate=" + IssuingDate + "\nvalidityFinishDate=" + validityFinishDate + "\nvalidity=" + validity + "\nsubjectName=" + subjectName + "\nsubjectPublicKey=" + publicK + "\nsignature=" + signature ; | |
} | |
public int getSerialNumber() { | |
return serialNumber; | |
} | |
public String getIssuerName() { | |
return issuerName; | |
} | |
public Date getIssuingDate() { | |
return IssuingDate; | |
} | |
public Date getValidityFinishDate() { | |
return validityFinishDate; | |
} | |
public int getValidity() { | |
return validity; | |
} | |
public String getSubjectName() { | |
return subjectName; | |
} | |
public PublicKey getSubjectPublicKey() { | |
return subjectPublicKey; | |
} | |
public byte[] getSignature() { | |
return signature; | |
} | |
public void setSerialNumber(int serialNumber) { | |
this.serialNumber = serialNumber; | |
} | |
public void setIssuerName(String issuerName) { | |
this.issuerName = issuerName; | |
} | |
public void setIssuingDate(Date IssuingDate) { | |
this.IssuingDate = IssuingDate; | |
} | |
public void setValidityFinishDate(Date validityFinishDate) { | |
this.validityFinishDate = validityFinishDate; | |
} | |
public void setValidity(int validity) { | |
this.validity = validity; | |
} | |
public void setSubjectName(String subjectName) { | |
this.subjectName = subjectName; | |
} | |
public void setSubjectPublicKey(PublicKey subjectPublicKey) { | |
this.subjectPublicKey = subjectPublicKey; | |
} | |
public void setSignature(byte[] signature) { | |
this.signature = signature; | |
} | |
public boolean Verify(PublicKey CAPublicKey){ | |
//test if the CA name is same as the CA of system: | |
if(!this.issuerName.equals("BitCionCA")) | |
return false; | |
//test if CA publicKey is right: | |
if(!VerficationSignature.verify(this.cerToByte(), this.getSignature(), CAPublicKey)) | |
return false; | |
//test certificate validity: | |
Date currentDate = new Date(); | |
if(currentDate.after(this.getValidityFinishDate())) | |
return false; | |
return true; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* To change this license header, choose License Headers in Project Properties. | |
* To change this template file, choose Tools | Templates | |
* and open the template in the editor. | |
*/ | |
package bitcion; | |
import java.security.InvalidKeyException; | |
import java.security.NoSuchAlgorithmException; | |
import java.security.NoSuchProviderException; | |
import java.security.PrivateKey; | |
import java.security.Signature; | |
import java.security.SignatureException; | |
import java.util.logging.Level; | |
import java.util.logging.Logger; | |
/** | |
* | |
* @author LaNa Sa | |
*/ | |
public class GenerateSignature { | |
public static byte[] generate(byte[] message,PrivateKey pk) | |
{ | |
Signature sig; | |
try { | |
sig = Signature.getInstance("MD5WithRSA"); | |
sig.initSign(pk); | |
sig.update(message); | |
return sig.sign(); | |
} catch (NoSuchAlgorithmException ex) { | |
Logger.getLogger(GenerateSignature.class.getName()).log(Level.SEVERE, null, ex); | |
return null; | |
} catch (InvalidKeyException ex) { | |
Logger.getLogger(GenerateSignature.class.getName()).log(Level.SEVERE, null, ex); | |
return null; | |
} catch (SignatureException ex) { | |
Logger.getLogger(GenerateSignature.class.getName()).log(Level.SEVERE, null, ex); | |
return null; | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* To change this license header, choose License Headers in Project Properties. | |
* To change this template file, choose Tools | Templates | |
* and open the template in the editor. | |
*/ | |
package bitcion; | |
/** | |
* | |
* @author LaNa Sa | |
*/ | |
import java.io.IOException; | |
import java.io.InputStream; | |
import java.io.ObjectInputStream; | |
import java.io.ObjectOutputStream; | |
import java.io.OutputStream; | |
import java.io.Serializable; | |
import java.security.*; | |
import java.security.spec.InvalidKeySpecException; | |
import java.util.logging.Level; | |
import java.util.logging.Logger; | |
import javax.crypto.*; | |
import javax.crypto.spec.IvParameterSpec; | |
import javax.crypto.spec.SecretKeySpec; | |
import sun.misc.*; | |
public class RSA { | |
public static SealedObject encrypt(Serializable message,Key kp) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IOException, IllegalBlockSizeException | |
{ | |
// Get an instance of the Cipher for RSA encryption/decryption | |
Cipher c = Cipher.getInstance("RSA"); | |
// Initiate the Cipher, telling it that it is going to Encrypt, giving it the public key | |
c.init(Cipher.ENCRYPT_MODE,kp); | |
// Encrypt that message using a new SealedObject and the Cipher we created before | |
SealedObject EncryptedMessage= new SealedObject( message, c); | |
return EncryptedMessage; | |
} | |
public static Object decrypt(SealedObject EncryptedMessage,Key kp) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IOException, ClassNotFoundException, IllegalBlockSizeException, BadPaddingException | |
{ | |
// Get an instance of the Cipher for RSA encryption/decryption | |
Cipher dec = Cipher.getInstance("RSA"); | |
// Initiate the Cipher, telling it that it is going to Decrypt, giving it the private key | |
dec.init(Cipher.DECRYPT_MODE, kp); | |
try { | |
return EncryptedMessage.getObject(dec); | |
} catch (ClassNotFoundException | IllegalBlockSizeException | BadPaddingException e) { | |
e.printStackTrace(); | |
return null; | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* To change this license header, choose License Headers in Project Properties. | |
* To change this template file, choose Tools | Templates | |
* and open the template in the editor. | |
*/ | |
package bitcion; | |
import java.io.ByteArrayInputStream; | |
import java.io.ByteArrayOutputStream; | |
import java.io.IOException; | |
import java.io.ObjectInputStream; | |
import java.io.ObjectOutputStream; | |
/** | |
* | |
* @author LaNa Sa | |
*/ | |
public class Serialization { | |
public static Object deserialize(byte[] bytes) throws IOException, ClassNotFoundException { | |
try(ByteArrayInputStream b = new ByteArrayInputStream(bytes)){ | |
try(ObjectInputStream o = new ObjectInputStream(b)){ | |
return o.readObject(); | |
} | |
} | |
} | |
public static byte[] serialize(Object obj) throws IOException { | |
try(ByteArrayOutputStream b = new ByteArrayOutputStream()){ | |
try(ObjectOutputStream o = new ObjectOutputStream(b)){ | |
o.writeObject(obj); | |
} | |
return b.toByteArray(); | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* To change this license header, choose License Headers in Project Properties. | |
* To change this template file, choose Tools | Templates | |
* and open the template in the editor. | |
*/ | |
package bitcion; | |
/** | |
* | |
* @author LaNa Sa | |
*/ | |
import static bitcion.ClientClass.readKeyPair; | |
import java.sql.PreparedStatement; | |
import java.sql.*; | |
import java.util.Date; | |
import java.util.logging.Level; | |
import java.util.logging.Logger; | |
import java.net.*; | |
import java.io.*; | |
import java.math.BigInteger; | |
import java.security.KeyFactory; | |
import java.security.KeyPair; | |
import java.security.KeyPairGenerator; | |
import java.security.NoSuchAlgorithmException; | |
import java.security.PrivateKey; | |
import java.security.PublicKey; | |
import java.security.SecureRandom; | |
import java.security.spec.InvalidKeySpecException; | |
import java.security.spec.PKCS8EncodedKeySpec; | |
import java.security.spec.X509EncodedKeySpec; | |
import java.util.ArrayList; | |
import java.util.List; | |
import javax.crypto.SealedObject; | |
import sun.misc.BASE64Decoder; | |
import sun.misc.BASE64Encoder; | |
public class ServerClass extends Thread{ | |
private ServerSocket serverSocket; | |
private KeyPair myPair; | |
private PublicKey CAPublicKey; | |
//for generate sssion key: | |
private SecureRandom random = new SecureRandom(); | |
public ServerClass(int port) throws IOException { | |
serverSocket = new ServerSocket(port); | |
// Get my KeyPair from file: | |
myPair = readKeyPair(); | |
//get CA publicKey: | |
CAPublicKey = readCAPublicKey(); | |
} | |
public String nextSessionId() { | |
return new BigInteger(130, random).toString(32); | |
} | |
public static KeyPair readKeyPair() throws FileNotFoundException | |
{ | |
BufferedReader br; | |
try { | |
br = new BufferedReader(new FileReader("serverPublicKey.txt")); | |
StringBuilder sb = new StringBuilder(); | |
String line = br.readLine(); | |
while (line != null) { | |
sb.append(line); | |
sb.append(System.lineSeparator()); | |
line = br.readLine(); | |
} | |
String publicK = sb.toString(); | |
//convert public key from String to PublicKey: | |
byte[] publicBytes = new BASE64Decoder().decodeBuffer(publicK); | |
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicBytes); | |
KeyFactory keyFactory = KeyFactory.getInstance("RSA"); | |
PublicKey pubKey = keyFactory.generatePublic(keySpec); | |
br.close(); | |
br = new BufferedReader(new FileReader("serverPrivateKey.txt")); | |
sb = new StringBuilder(); | |
line = br.readLine(); | |
while (line != null) { | |
sb.append(line); | |
sb.append(System.lineSeparator()); | |
line = br.readLine(); | |
} | |
String privateK = sb.toString(); | |
//convert private key from String to PublicKey: | |
byte[] privateBytes = new BASE64Decoder().decodeBuffer(privateK); | |
PKCS8EncodedKeySpec keySpec2 = new PKCS8EncodedKeySpec(privateBytes); | |
PrivateKey privKey = keyFactory.generatePrivate(keySpec2); | |
br.close(); | |
//genrate keyPair: | |
return new KeyPair(pubKey, privKey); | |
} catch (IOException ex) { | |
Logger.getLogger(ClientClass.class.getName()).log(Level.SEVERE, null, ex); | |
return null; | |
} catch (NoSuchAlgorithmException ex) { | |
Logger.getLogger(ClientClass.class.getName()).log(Level.SEVERE, null, ex); | |
return null; | |
} catch (InvalidKeySpecException ex) { | |
Logger.getLogger(ClientClass.class.getName()).log(Level.SEVERE, null, ex); | |
return null; | |
} | |
} | |
public static PublicKey readCAPublicKey(){ | |
BufferedReader br; | |
try { | |
br = new BufferedReader(new FileReader("SystemCAPublicKey.txt")); | |
StringBuilder sb = new StringBuilder(); | |
String line = br.readLine(); | |
while (line != null) { | |
sb.append(line); | |
sb.append(System.lineSeparator()); | |
line = br.readLine(); | |
} | |
String publicK = sb.toString(); | |
//convert public key from String to PublicKey: | |
byte[] publicBytes = new BASE64Decoder().decodeBuffer(publicK); | |
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicBytes); | |
KeyFactory keyFactory = KeyFactory.getInstance("RSA"); | |
PublicKey pubKey = keyFactory.generatePublic(keySpec); | |
br.close(); | |
return pubKey; | |
} catch (FileNotFoundException ex) { | |
Logger.getLogger(ServerClass.class.getName()).log(Level.SEVERE, null, ex); | |
return null; | |
} catch (IOException ex) { | |
Logger.getLogger(ServerClass.class.getName()).log(Level.SEVERE, null, ex); | |
return null; | |
} catch (NoSuchAlgorithmException ex) { | |
Logger.getLogger(ServerClass.class.getName()).log(Level.SEVERE, null, ex); | |
return null; | |
} catch (InvalidKeySpecException ex) { | |
Logger.getLogger(ServerClass.class.getName()).log(Level.SEVERE, null, ex); | |
return null; | |
} | |
} | |
public void run() { | |
while(true) { | |
try { | |
System.out.println("Waiting for client on port " + | |
serverSocket.getLocalPort() + "..."); | |
Socket server = serverSocket.accept(); | |
System.out.println("Just connected to " + server.getRemoteSocketAddress()); | |
ObjectInputStream in = new ObjectInputStream(server.getInputStream()); | |
ObjectOutputStream out = new ObjectOutputStream(server.getOutputStream()); | |
//recive operator number from client: | |
String operator_number =(String) in.readObject(); | |
System.out.println("operator number: " + operator_number); | |
switch(operator_number){ | |
case "signUp": | |
{ | |
//recive certificate from client: | |
DigitalCertificate cer = (DigitalCertificate) in.readObject(); | |
//verify the recived certification: | |
boolean verifyResult = cerVerify(cer); | |
if(verifyResult) | |
{ | |
//insert client certificate in database: | |
insertNewClientCertificate(cer); | |
//reciv client account and save it in database: | |
SystemClient c = (SystemClient) in.readObject(); | |
insertNewClient(c, cer); | |
}else | |
{ | |
System.out.println("Certificate isn't Validate."); | |
} | |
break; | |
} | |
case "1": | |
{ | |
//send server publicKey to client: | |
out.writeObject(myPair.getPublic()); | |
out.flush(); | |
//get clientIP: | |
String clientIP = (String)in.readObject(); | |
//get client publicKey from DB by ip: | |
PublicKey clientPK = getClientPublicKey(clientIP); | |
//generate session key: | |
String sessionKey = nextSessionId(); | |
//Encrypt session key with RSA: | |
SealedObject enc_session_key = RSA.encrypt(sessionKey, myPair.getPrivate()); | |
//send session key: | |
out.writeObject(enc_session_key); | |
out.flush(); | |
//Sending Data: | |
List<SystemClient> sendData = getClientTableQuery(); | |
//Encrypt sending data and send(write) it in socket: | |
SealedObject encrypted_data = AES.encrypt((Serializable) sendData,sessionKey.getBytes()); | |
out.writeObject(encrypted_data); | |
out.flush(); | |
break; | |
} | |
case "2": | |
{ | |
//send server publicKey to client: | |
out.writeObject(myPair.getPublic()); | |
out.flush(); | |
//get clientIP: | |
String clientIP = (String)in.readObject(); | |
//get client publicKey from DB by ip: | |
PublicKey clientPK = getClientPublicKey(clientIP); | |
//generate session key: | |
String sessionKey = nextSessionId(); | |
//Encrypt session key with RSA: | |
SealedObject enc_session_key = RSA.encrypt(sessionKey, myPair.getPrivate()); | |
//send session key: | |
out.writeObject(enc_session_key); | |
out.flush(); | |
//recive transaction from client: | |
SealedObject EncryptedMessage = (SealedObject) in.readObject(); | |
Transaction recv_message = (Transaction) AES.decrypt(EncryptedMessage,sessionKey.getBytes()); | |
//print transaction on screen | |
System.out.println(recv_message.toString()); | |
//recive digital signature from client: | |
DataInputStream din = new DataInputStream(server.getInputStream()); | |
int digital_sig_len = din.readInt(); | |
InputStream srm_in = server.getInputStream(); | |
byte[] digital_sig = new byte[digital_sig_len]; | |
srm_in.read(digital_sig,0,digital_sig_len); | |
//virefcation of dital seg: | |
byte[] messageBytes = Serialization.serialize(EncryptedMessage); | |
boolean ver_result = VerficationSignature.verify(messageBytes, digital_sig, clientPK); | |
//test validation of transaction: | |
if(!ver_result) | |
{ | |
System.out.println("the transaction is rejected...\nSignature isn't correct.."); | |
}else if(getClientAccountValue(recv_message.senderIP) < recv_message.value) | |
{ | |
System.out.println("the transaction is rejected...\nAccount value is less than transaction value"); | |
out.flush(); | |
out.writeObject(new String("the transaction is rejected...\nAccount value is less than transaction value")); | |
}else | |
{ | |
insertTransaction(recv_message,digital_sig.toString()); | |
out.flush(); | |
out.writeObject(new String("Transaction Done Sucssefuly.")); | |
} | |
break; | |
} | |
} | |
server.close(); | |
}catch(SocketTimeoutException s) { | |
System.out.println("Socket timed out!"); | |
break; | |
}catch(IOException e) { | |
e.printStackTrace(); | |
break; | |
} catch (Exception ex) { | |
Logger.getLogger(ServerClass.class.getName()).log(Level.SEVERE, null, ex); | |
} | |
} | |
} | |
public List<SystemClient> getClientTableQuery() | |
{ | |
List<SystemClient> result = new ArrayList<SystemClient>(); | |
String host = "jdbc:derby://localhost:1527/Bitcion"; | |
String username = "bitcion"; | |
String password = "bitcion"; | |
try { | |
Connection con = DriverManager.getConnection( host, username, password ); | |
Statement stmt = con.createStatement(); | |
String SQL = "SELECT * FROM CLIENTS"; | |
ResultSet rs = stmt.executeQuery(SQL); | |
while(rs.next()) | |
{ | |
SystemClient ct = new SystemClient(); | |
ct.ip =rs.getString("IP"); | |
ct.value =rs.getInt("VALUE"); | |
result.add(ct); | |
} | |
} catch (SQLException ex) { | |
Logger.getLogger(ServerClass.class.getName()).log(Level.SEVERE, null, ex); | |
} | |
return result; | |
} | |
public int getClientAccountValue(String clientIP) | |
{ | |
int result = 0; | |
String host = "jdbc:derby://localhost:1527/Bitcion"; | |
String username = "bitcion"; | |
String password = "bitcion"; | |
try { | |
Connection con = DriverManager.getConnection( host, username, password ); | |
PreparedStatement statement = con.prepareStatement("select * from CLIENTS where IP = ?"); | |
statement.setString(1, clientIP); | |
ResultSet rs = statement.executeQuery(); | |
rs.next(); | |
result = rs.getInt("VALUE"); | |
} catch (SQLException ex) { | |
Logger.getLogger(ServerClass.class.getName()).log(Level.SEVERE, null, ex); | |
} | |
return result; | |
} | |
public void insertTransaction(Transaction t,String digital_signature) | |
{ | |
String host = "jdbc:derby://localhost:1527/Bitcion"; | |
String username = "bitcion"; | |
String password = "bitcion"; | |
try { | |
Connection con = DriverManager.getConnection( host, username, password ); | |
//Insert transaction in transactions tabel: | |
PreparedStatement statement = con.prepareStatement("INSERT INTO TRANSACTIONS VALUES ( ? , ? , ? , ?) "); | |
statement.setString(1,t.senderIP); | |
statement.setString(2,t.reciverIP); | |
statement.setInt(3,t.value); | |
statement.setString(4,digital_signature); | |
statement.execute(); | |
//Update sender account: | |
statement = con.prepareStatement("UPDATE CLIENTS SET VALUE = VALUE - ? WHERE IP = ?"); | |
statement.setInt(1,t.value); | |
statement.setString(2,t.senderIP); | |
statement.execute(); | |
//Update reciver account: | |
statement = con.prepareStatement("UPDATE CLIENTS SET VALUE = VALUE + ? WHERE IP = ?"); | |
statement.setInt(1,t.value); | |
statement.setString(2,t.reciverIP); | |
statement.execute(); | |
} catch (SQLException ex) { | |
Logger.getLogger(ServerClass.class.getName()).log(Level.SEVERE, null, ex); | |
} | |
} | |
private boolean cerVerify(DigitalCertificate cer){ | |
//test if the CA name is same as the CA of system: | |
if(!cer.getIssuerName().equals("BitCionCA")) | |
return false; | |
//test if CA publicKey is right: | |
if(!VerficationSignature.verify(cer.cerToByte(), cer.getSignature(), CAPublicKey)) | |
return false; | |
//test certificate validity: | |
Date currentDate = new Date(); | |
if(currentDate.after(cer.getValidityFinishDate())) | |
return false; | |
return true; | |
} | |
private void insertNewClientCertificate(DigitalCertificate cer) | |
{ | |
String host = "jdbc:derby://localhost:1527/Bitcion"; | |
String username = "bitcion"; | |
String password = "bitcion"; | |
try { | |
Connection con = DriverManager.getConnection( host, username, password ); | |
//Insert transaction in transactions tabel: | |
PreparedStatement statement = con.prepareStatement("INSERT INTO CERTIFICATES VALUES ( ? , ? , ? , ? , ? , ? , ?) "); | |
statement.setInt(1,cer.getSerialNumber()); | |
statement.setString(2,cer.getIssuerName()); | |
statement.setDate(3,new java.sql.Date(cer.getIssuingDate().getTime())); | |
statement.setDate(4,new java.sql.Date(cer.getValidityFinishDate().getTime())); | |
statement.setString(5,cer.getSubjectName()); | |
statement.setString(6,cer.getSignature().toString()); | |
//encode public key as string and then store it in DB: | |
String publicK = new BASE64Encoder().encode(cer.getSubjectPublicKey().getEncoded()); | |
statement.setString(7,publicK); | |
statement.execute(); | |
} catch (SQLException ex) { | |
Logger.getLogger(ServerClass.class.getName()).log(Level.SEVERE, null, ex); | |
} | |
} | |
private void insertNewClient(SystemClient c,DigitalCertificate cer) | |
{ | |
String host = "jdbc:derby://localhost:1527/Bitcion"; | |
String username = "bitcion"; | |
String password = "bitcion"; | |
try { | |
Connection con = DriverManager.getConnection( host, username, password ); | |
//Insert transaction in transactions tabel: | |
PreparedStatement statement = con.prepareStatement("INSERT INTO CLIENTS VALUES ( ? , ? , ?) "); | |
statement.setString(1,c.ip); | |
statement.setInt(2,c.value); | |
statement.setInt(3,cer.getSerialNumber()); | |
statement.execute(); | |
} catch (SQLException ex) { | |
Logger.getLogger(ServerClass.class.getName()).log(Level.SEVERE, null, ex); | |
} | |
} | |
private PublicKey getClientPublicKey(String clientIP){ | |
String host = "jdbc:derby://localhost:1527/Bitcion"; | |
String username = "bitcion"; | |
String password = "bitcion"; | |
try { | |
Connection con = DriverManager.getConnection( host, username, password ); | |
PreparedStatement statement = con.prepareStatement("select * from CERTIFICATES where SUBJECTNAME = ?"); | |
statement.setString(1, clientIP); | |
ResultSet rs = statement.executeQuery(); | |
rs.next(); | |
String publicK = rs.getString(7); | |
//convert public key from String to PublicKey: | |
byte[] publicBytes = new BASE64Decoder().decodeBuffer(publicK); | |
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicBytes); | |
KeyFactory keyFactory = KeyFactory.getInstance("RSA"); | |
PublicKey pubKey = keyFactory.generatePublic(keySpec); | |
return pubKey; | |
} catch (SQLException ex) { | |
Logger.getLogger(ServerClass.class.getName()).log(Level.SEVERE, null, ex); | |
return null; | |
} catch (IOException ex) { | |
Logger.getLogger(ServerClass.class.getName()).log(Level.SEVERE, null, ex); | |
return null; | |
} catch (NoSuchAlgorithmException ex) { | |
Logger.getLogger(ServerClass.class.getName()).log(Level.SEVERE, null, ex); | |
return null; | |
} catch (InvalidKeySpecException ex) { | |
Logger.getLogger(ServerClass.class.getName()).log(Level.SEVERE, null, ex); | |
return null; | |
} | |
} | |
public static void main(String[] args) { | |
try { | |
ServerClass server = new ServerClass(6000); | |
server.start(); | |
// System.out.println(server.getClientTableQuery()); | |
} catch (IOException ex) { | |
Logger.getLogger(ServerClass.class.getName()).log(Level.SEVERE, null, ex); | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* To change this license header, choose License Headers in Project Properties. | |
* To change this template file, choose Tools | Templates | |
* and open the template in the editor. | |
*/ | |
package bitcion; | |
import java.io.*; | |
/** | |
* | |
* @author LaNa Sa | |
*/ | |
public class SystemClient implements Serializable{ | |
public String ip; | |
public int value; | |
@Override | |
public String toString() { | |
return "ip :" + ip + ", value :" + value ; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* To change this license header, choose License Headers in Project Properties. | |
* To change this template file, choose Tools | Templates | |
* and open the template in the editor. | |
*/ | |
package bitcion; | |
import java.io.*; | |
/** | |
* | |
* @author LaNa Sa | |
*/ | |
public class Transaction implements Serializable { | |
public String senderIP; | |
public String reciverIP; | |
public int value; | |
public Transaction() { | |
} | |
public Transaction(String senderIP, String reciverIP, int value) { | |
this.senderIP = senderIP; | |
this.reciverIP = reciverIP; | |
this.value = value; | |
} | |
@Override | |
public String toString() { | |
return "Transaction{" + "senderIP=" + senderIP + ", reciverIP=" + reciverIP + ", value=" + value + '}'; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* To change this license header, choose License Headers in Project Properties. | |
* To change this template file, choose Tools | Templates | |
* and open the template in the editor. | |
*/ | |
package bitcion; | |
import java.security.InvalidKeyException; | |
import java.security.NoSuchAlgorithmException; | |
import java.security.NoSuchProviderException; | |
import java.security.PublicKey; | |
import java.security.Signature; | |
import java.security.SignatureException; | |
import java.util.logging.Level; | |
import java.util.logging.Logger; | |
/** | |
* | |
* @author LaNa Sa | |
*/ | |
public class VerficationSignature { | |
public static boolean verify(byte[] message,byte[] sigToVerify,PublicKey pk) | |
{ | |
Signature sig; | |
try { | |
sig = Signature.getInstance("MD5WithRSA"); | |
sig.initVerify(pk); | |
sig.update(message); | |
return sig.verify(sigToVerify); | |
} catch (NoSuchAlgorithmException ex) { | |
Logger.getLogger(VerficationSignature.class.getName()).log(Level.SEVERE, null, ex); | |
return false; | |
}catch (InvalidKeyException ex) { | |
Logger.getLogger(VerficationSignature.class.getName()).log(Level.SEVERE, null, ex); | |
return false; | |
} catch (SignatureException ex) { | |
Logger.getLogger(VerficationSignature.class.getName()).log(Level.SEVERE, null, ex); | |
return false; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment