I been working on this for days.
Our backend have a signature checking which is done using PHP:
private $HMAC_ALGO = 'md5';
public function decodeAndValidateMessage($data,$signature,$secretkey) {
if (!is_string($data)) {
throw new InvalidRequestException($data);
}
$decodedData = base64_decode($data);
// if not json returned the throw exception...
$jsonDecoded = json_decode($decodedData,true);
if (!$jsonDecoded) {
throw new InvalidRequestException($decodedData);
}
// validate
$signatureRef = base64_encode(hash_hmac($this->HMAC_ALGO,$decodedData,$secretkey,true));
if ($signature === $signatureRef) {
return $jsonDecoded;
} else {
throw new InvalidSignatureException();
}
}
I made it work on iOS:
func hmac(_ algorithm: HMACAlgorithm, key: String) -> String {
let cKey = key.cString(using: String.Encoding.utf8)
let cData = self.cString(using: String.Encoding.utf8)
var result = [CUnsignedChar](repeating: 0, count: Int(algorithm.digestLength()))
CCHmac(algorithm.toCCHmacAlgorithm(), cKey!, Int(strlen(cKey!)), cData!, Int(strlen(cData!)), &result)
let hmacData:Data = Data(bytes: UnsafePointer<UInt8>(result), count: (Int(algorithm.digestLength())))
let hmacBase64 = hmacData.base64EncodedString(options: NSData.Base64EncodingOptions(rawValue: 0))
print(String(hmacBase64))
return String(hmacBase64)
}
Any idea/help on doing this on Kotlin/Android? I'm being stuck on InvalidSignatureException error.
fun generateSignature(data : HashMap<String, Any>) : String {
val hmac = Mac.getInstance("HmacMD5")
hmac.init(SecretKeySpec(Constant.PRIVATEKEY.toByteArray(Charsets.UTF_8), hmac.algorithm))
return Base64.encodeToString(data.toString().toByteArray(),Base64.URL_SAFE + Base64.NO_PADDING + Base64.NO_CLOSE + Base64.NO_WRAP)
}
Thanks :D I really appreciate for any help :D
Update:
Just to make my question simpler?
Is it possible to make translate the iOS line of code to Kotlin?
enum HMACAlgorithm {
case md5, sha1, sha224, sha256, sha384, sha512
func toCCHmacAlgorithm() -> CCHmacAlgorithm {
var result: Int = 0
switch self {
case .md5:
result = kCCHmacAlgMD5
case .sha1:
result = kCCHmacAlgSHA1
case .sha224:
result = kCCHmacAlgSHA224
case .sha256:
result = kCCHmacAlgSHA256
case .sha384:
result = kCCHmacAlgSHA384
case .sha512:
result = kCCHmacAlgSHA512
}
return CCHmacAlgorithm(result)
}
func digestLength() -> Int {
var result: CInt = 0
switch self {
case .md5:
result = CC_MD5_DIGEST_LENGTH
case .sha1:
result = CC_SHA1_DIGEST_LENGTH
case .sha224:
result = CC_SHA224_DIGEST_LENGTH
case .sha256:
result = CC_SHA256_DIGEST_LENGTH
case .sha384:
result = CC_SHA384_DIGEST_LENGTH
case .sha512:
result = CC_SHA512_DIGEST_LENGTH
}
return Int(result)
}
}
this is how I call the function
var params : Dictionary
params.generateSignature()
fun generateSignature(data : HashMap) : String {
val hmac = Mac.getInstance("HmacMD5")
hmac.init(SecretKeySpec(Constant.PRIVATEKEY.toByteArray(Charsets.UTF_8), hmac.algorithm))
return Base64.encodeToString(data.toString().toByteArray(),Base64.URL_SAFE + Base64.NO_PADDING + Base64.NO_CLOSE + Base64.NO_WRAP)
}
Someone finally found out the answer.
My mistake is hashmap should be run under JSONObject
var obj = JsonObject(data)
and use obj.toString() :D
Related
I am a student studying Volley request.
There's an error that I can't solve, so I'm asking you to find a solution.
I don't understand why can't POST from Android to PHP at all.
It worked well in other situations, but not only in JsonArrayRequest.
I'll attach the code, so if there's any problem with my code, please let me know.
This is string request code in Android Studio
package kr.ac.castcommunity.cc.request
import android.util.Log
import com.android.volley.Request
import com.android.volley.Response
import com.android.volley.Response.success
import com.android.volley.toolbox.JsonArrayRequest
import com.android.volley.toolbox.StringRequest
import java.util.HashMap
import org.json.JSONObject
import com.android.volley.toolbox.JsonObjectRequest
import org.json.JSONArray
class CommentRequest(boardid : String , listener: Response.Listener<JSONArray>) :
JsonArrayRequest(Request.Method.POST, URL, JSONArray(), listener, Response.ErrorListener { error ->
Log.d("COMMENT ERROR", "Server Response FAIL: $error")
}) {
private val parameters: MutableMap<String, String>
companion object {
private val URL = "http://MyIP/cc/commentlist.php"
}
init {
parameters = HashMap()
parameters["boardid"] = boardid
Log.d("boardID :",boardid)
}
override fun getParams(): Map<String, String> {
return parameters
}
}
This is PHP code
(It works well if I randomly assign a variable.)
(But it doesn't work when I interlock it.)
<?php
$con = mysqli_connect("localhost", "root", "root", "cc");
mysqli_query($con, 'SET NAMES utf8');
$boardid = $_POST["boardid"]; // but It's not operating
//$boardid = "1"; // It's operating
$boardid = (int)$boardid;
$statement = mysqli_prepare($con, "select * from comment where boardid = ?");
mysqli_stmt_bind_param($statement, "i", $boardid);
mysqli_stmt_execute($statement);
mysqli_stmt_store_result($statement);
mysqli_stmt_bind_result($statement, $commentid, $boardid, $content, $writer, $date);
$response = array();
$response["success"] = false;
$result = array();
while(mysqli_stmt_fetch($statement)){
$response["success"] = true;
$response["commentid"] = $commentid;
$response["boardid"] = $boardid;
$response["content"] = $content;
$response["writer"] = $writer;
$response["date"] = substr($date,10,-3);
array_push($result, array(
"success"=>$response["success"],
"commentid" => $response["commentid"],
"boardid" => $response["boardid"],
"content" => $response["content"],
"writer" => $response["writer"],
"date" => $response["date"]));
}
echo json_encode($result);
?>
D/COMMENTÂ ERROR: Server Response Fail: com.android.volley.ParseError: org.json.JSONException: Value <br of type java.lang.String cannot be converted to JSONArray
and response code
val boardid = intent.getIntExtra("bnum", 0)
mCommentRecyclerView = comment_recyclerView
val responseListener = Response.Listener<JSONArray> { response ->
try {
Log.d("response", "comment response Start")
for (i in 0 until response.length()) {
val jobject = response.getJSONObject(i)
val success = jobject.getBoolean("success")
val boardid = jobject.getInt("boardid")
val commentid = jobject.getInt("commentid")
val content = jobject.getString("content")
val date = jobject.getString("date")
val writer = jobject.getString("writer")
if (success == true) {
mDatas.add(Comment(boardid, commentid, content, date, writer))
} else {
return#Listener
}
}
mAdpater = CommentAdapter(this, mDatas)
mCommentRecyclerView!!.adapter = mAdpater
mCommentRecyclerView!!.addItemDecoration(BoardDecoration(20))
val lm = LinearLayoutManager(this)
lm.reverseLayout = true
lm.stackFromEnd = true
mCommentRecyclerView!!.layoutManager = lm
mCommentRecyclerView!!.setHasFixedSize(true)
val decoration = DividerItemDecoration(this, LinearLayoutManager.VERTICAL)
mCommentRecyclerView!!.addItemDecoration(decoration)
} catch (e: JSONException) {
e.printStackTrace()
}
}
val commentRequest = CommentRequest(boardid.toString(), responseListener)
val queue = Volley.newRequestQueue(this#DetailActivity)
queue.add(commentRequest)
I really don't know why. I need your help.
Through your error message. I think there is a problem with the conversion of String to JsonObject.
You can print out the response from the server first, and then print out the conversion parameters.
I think the error appears in the for loop code below. Please check if the error is caused by the <br> tag.
Log.d("response", "comment response Start")
for (i in 0 until response.length()) {
val jobject = response.getJSONObject(i)
val success = jobject.getBoolean("success")
val boardid = jobject.getInt("boardid")
val commentid = jobject.getInt("commentid")
val content = jobject.getString("content")
val date = jobject.getString("date")
val writer = jobject.getString("writer")
println(jobject)
println(success)
println(boardid)
println(commentid)
println(content)
println(date)
println(writer)
if (success == true) {
mDatas.add(Comment(boardid, commentid, content, date, writer))
} else {
return#Listener
}
}
I am creating an app similar to those from online stores
I did an ArrayList for products added to the shopping cart.
How I must do to send this into my PHP script and add this to MySQL database.
I tried return count of my ArrayList elements, but I can't.
This is PHP code:
<?php
$postedArray = $_POST["arrayToPOST"];
$response = array();
if(isset($postedArray))
{
$count = count($postedArray);
$response["Count"] = $count;
$response["postedArray"] = $postedArray;
}
else
{
$response["Count"] = 0;
$response["postedArray"] = "ERROR ON POST";
}
echo json_encode($response);
?>
This is my function in Android app:
val arrayList: ArrayList<String> = ArrayList<String>()
arrayList.add("First value")
arrayList.add("Second value")
arrayList.add("Third value")
val gson = GsonBuilder()
.setLenient()
.create()
val retrofit = Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create(gson))
.baseUrl("http://192.168.100.11/")
.build()
val webAPIInterface = retrofit.create(WebAPIInterface::class.java)
var call = webAPIInterface.postData(arrayList)
call.enqueue(object : Callback<ResponsePOJO> {
override fun onFailure(call: Call<ResponsePOJO>?, t: Throwable?) {
Log.e("MainActivity", "Retrofit 2 ERROR: "+t.toString())
}
override fun onResponse(call: Call<ResponsePOJO>?, response: Response<ResponsePOJO>?)
{
Log.v("MainActivity", "RESPONSE: "+response!!.body().toString())
if(response!!.isSuccessful)
{
Log.v("MainActivity", "Response is successful")
Log.v("MainActivity", "")
}
else
{
Log.e("MainActivity", "Response isnt successful")
}
}
})
I looking for solution in internet, but I found nothing.
Please help !
I wanna make Laravel encryption in iOS Swift 3.
Crypt::encrypt('123456');
I tried something like this but it does not work for. I think something is wrong in this code:
func generateRandomBytes() -> String? {
var keyData = Data(count: 10)
let result = keyData.withUnsafeMutableBytes {
(mutableBytes: UnsafeMutablePointer<UInt8>) -> Int32 in
SecRandomCopyBytes(kSecRandomDefault, keyData.count, mutableBytes)
}
if result == errSecSuccess {
return keyData.base64EncodedString()
} else {
print("Problem generating random bytes")
return nil
}
}
override func viewDidLoad() {
super.viewDidLoad()
let ivString:String = generateRandomBytes()!
let ivDecodedData : Data = ivString.data(using: .utf8)!
print("iv : ",ivString ,ivString.characters.count)
let purePasswordString:String = "123456"
let serialString = String(format:"s:%lu:\"%#\";",purePasswordString.characters.count,purePasswordString)
let keyString = "u6KuXJLIUwEUl7noY8J8H1ffDRwLC/5gjaWW1qTQ3hE="
let encryptedStrKEYData = NSData(base64Encoded: keyString, options: .init(rawValue: 0))!
let encryptedStrKEYDataString:String = NSString(data: encryptedStrKEYData as Data, encoding: String.Encoding.ascii.rawValue)! as String
let keyData: Data = Data(base64Encoded: keyString)!
let message = serialString
let data: NSData! = (message as NSString).data(using: String.Encoding.ascii.rawValue) as NSData!
let cryptData = NSMutableData(length: Int(data.length) + kCCBlockSizeAES128)!
let keyLength = size_t(kCCKeySizeAES256)
let operation: CCOperation = UInt32(kCCEncrypt)
let algoritm: CCAlgorithm = UInt32(kCCAlgorithmAES128)
let options: CCOptions = UInt32(kCCOptionPKCS7Padding)
var numBytesEncrypted :size_t = 0
let cryptStatus = CCCrypt(operation,
algoritm,
options,
keyData.bytes,
keyLength,
ivDecodedData.bytes,
data.bytes,
data.length,
cryptData.mutableBytes,
cryptData.length,
&numBytesEncrypted)
if UInt32(cryptStatus) == UInt32(kCCSuccess) {
cryptData.length = Int(numBytesEncrypted)
print("cryptLength = \(numBytesEncrypted), cryptData = \(cryptData)")
let base64cryptString = cryptData.base64EncodedString(options: [.lineLength64Characters])
let mix:String = String(format:"%#%#",ivString,base64cryptString)
let cKey = encryptedStrKEYDataString.cString(using: String.Encoding.utf8)
let cData = mix.cString(using: String.Encoding.utf8)
let algorithm = CCHmacAlgorithm(kCCHmacAlgSHA256)
let size = Int(CC_SHA256_DIGEST_LENGTH)
var result = [CUnsignedChar](repeating: 0, count: size )
CCHmac(algorithm, cKey!, Int(strlen(cKey!)), cData!, Int(strlen(cData!)), &result)
let hmacData:NSData = NSData(bytes: result, length: size)
let hmacBase64 = hmacData.base64EncodedString(options: [])
let dict:Dictionary = ["iv":ivString,"value":base64cryptString,"mac":hmacBase64]
do {
let jsonData = try JSONSerialization.data(withJSONObject: dict, options: .init(rawValue: 0))
let j:String = jsonData.base64EncodedString()
print("done: ", j , j.characters.count)
} catch {
print(error.localizedDescription)
}
} else {
print("Error: \(cryptStatus)")
}
}
And see this to help you:
https://github.com/reza-khalafi/LaravelCrypt/blob/master/laravelEncrypt.php
And this is my last try:
import UIKit
class Enc2ViewController: UIViewController {
func generateRandomBytes() -> String? {
var keyData = Data(count: 10)
let result = keyData.withUnsafeMutableBytes {
(mutableBytes: UnsafeMutablePointer<UInt8>) -> Int32 in
SecRandomCopyBytes(kSecRandomDefault, keyData.count, mutableBytes)
}
if result == errSecSuccess {
return keyData.base64EncodedString()
} else {
print("Problem generating random bytes")
return nil
}
}
override func viewDidLoad() {
super.viewDidLoad()
let iv = generateRandomBytes()! // fixed 16 chars.
print("iv String: \(iv)")
let cryptoKeyString = "u6KuXJLIUwEUl7noY8J8H1ffDRwLC/5gjaWW1qTQ3hE="
let pureMessageString:String = "123456"
let originalString = String(format:"s:%lu:\"%#\";",pureMessageString.characters.count,pureMessageString)
print("Original String: \(originalString)")
let key:String = cryptoKeyString
if let keyData = key.data(using: String.Encoding.utf8),
let data = originalString.data(using: String.Encoding.utf8),
let cryptData = NSMutableData(length: Int((data.count)) + kCCBlockSizeAES128) {
let keyLength = size_t(kCCKeySizeAES256)
let operation: CCOperation = UInt32(kCCEncrypt)
let algoritm: CCAlgorithm = UInt32(kCCAlgorithmAES128)
let options: CCOptions = UInt32(kCCOptionPKCS7Padding)
var numBytesEncrypted :size_t = 0
let base64cryptStringOut = keyData.withUnsafeBytes {(keyBytes: UnsafePointer<CChar>)->String? in
return data.withUnsafeBytes {(dataBytes: UnsafePointer<CChar>)->String? in
let cryptStatus = CCCrypt(operation,
algoritm,
options,
keyBytes, keyLength,
iv,
dataBytes, data.count,
cryptData.mutableBytes, cryptData.length,
&numBytesEncrypted)
if UInt32(cryptStatus) == UInt32(kCCSuccess) {
cryptData.length = Int(numBytesEncrypted)
let base64cryptString = cryptData.base64EncodedString(options: .lineLength64Characters)
return base64cryptString
}
else {
return nil
}
}
}
print("base64cryptStringOut: \(String(describing: base64cryptStringOut)) ")
let bIv:String = Data(iv.utf8).base64EncodedString()
print("bIv",bIv,bIv.characters.count)
let mixStr:String = String(format:"%#%#",bIv,base64cryptStringOut!)
print("mix: ",mixStr,mixStr.characters.count)
var result: [CUnsignedChar]
if let cKey = key.cString(using: String.Encoding.utf8),
let cData = mixStr.cString(using: String.Encoding.utf8)
{
let algo = CCHmacAlgorithm(kCCHmacAlgSHA256)
result = Array(repeating: 0, count: Int(CC_SHA256_DIGEST_LENGTH))
CCHmac(algo, cKey, cKey.count, cData, cData.count, &result)
}
else {
fatalError("Nil returned when processing input strings as UTF8")
}
var hexString = ""
for byte in result {
hexString += String(format:"%2hhx", UInt8(byte))
}
print("hmac-string: \(hexString) \(hexString.characters.count)")
let dict:Dictionary = ["iv":bIv,"value":base64cryptStringOut,"mac":hexString]
do {
let jsonData = try JSONSerialization.data(withJSONObject: dict, options: .init(rawValue: 0))
// here "jsonData" is the dictionary encoded in JSON data
print(jsonData)
let j:String = jsonData.base64EncodedString()
print("done: ", j , j.characters.count)
} catch {
print(error.localizedDescription)
}
}
}//didload
}
Solved:
Finally we make it after too much time research about Laravel encryption, Decided to create by own. LaraCrypt solved the problem. try this:
pod 'LaraCrypt'
Laravel Encryption with Swift language
Enjoy.
im trying to establish secure RSA connection between PHP server and Unity 3D game (in Web Player). At the end of process $rsa->decrypt() return "false" :-(
Server generate RSA keys and send public key to Unity:
$rsa = new Crypt_RSA();
$rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);
$rsa->setPrivateKeyFormat(CRYPT_RSA_PRIVATE_FORMAT_PKCS1);
$rsa->setPublicKeyFormat(CRYPT_RSA_PUBLIC_FORMAT_PKCS1);
$keys = $rsa->createKey(512);
extract($keys);
$rsa->loadKey($publickey);
$_SESSION["privatekey"] = $privatekey;
$this->payload->Modulus = base64_encode($rsa->modulus);
$this->payload->Exponent = base64_encode($rsa->publicExponent);
This generate JSON:
{"Modulus":"MTE5MjcyOTYyNjQzMTIzODQ1MTI4MjE2ODA3OTY2MDE5MDQwODQ1NTc0MDIzMDI0NDQ5MjAzMDY4NDgxNTkyNzk5MTc0MzYxMzI4MDA3Njk0MjI4NjAyMzAwODA4MDI5MzkwOTk2MjUyMTg5OTkwNDgwNzg3MDcwMjk4MjkxMjcxNjQ1NzMzNDg0MTcxNTc0MDM3ODM0NjE3ODE=","Exponent":"NjU1Mzc="}
Unity ENCODER:
var N = JSON.Parse (generatedJSON); //im using SimpleJSON library
var publicKey = new RSAParameters ();
publicKey.Modulus = Convert.FromBase64String(N ["Modulus"].Value);
publicKey.Exponent = Convert.FromBase64String(N ["Exponent"].Value);
var csp = new RSACryptoServiceProvider(512);
csp.ImportParameters(publicKey);
var plainTextData = "Hello Wordl"; //here come AES key generator (not implemented yet)
var bytesPlainTextData = System.Text.Encoding.Unicode.GetBytes(plainTextData);
var bytesCypherText = csp.Encrypt(bytesPlainTextData, false);
var cypherText = Convert.ToBase64String(bytesCypherText);
Unity response:
Nqsno9tTXWr4UfwoXQcHwzwnusvdKWpVGoakSsVECh3lH/3bNaPKY9LzZ9iZIs8RI9e5EI+GvegnxrW5xoqnyrDHbF8AuWh9Hndnn0OS5SV/kiYeBT6Wn9pxwjq5MoixM3geushHpvGTDQV0NOLcsXTdv8tG0CvFZip31GpMp9C/OalxolpaUvk65YBJ0dJcyNiuD08PQJAupJXKnVgfLZ0i1GrjQ7guHO6OmEUKDyQcZ5Sf/6yJry3Mhv2R4ioR/jU+mL4tLKuix5+/XKmBjg==
And server DECODER:
$rsa = new Crypt_RSA();
$rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);
$rsa->setPrivateKeyFormat(CRYPT_RSA_PRIVATE_FORMAT_PKCS1);
$rsa->setPublicKeyFormat(CRYPT_RSA_PUBLIC_FORMAT_PKCS1);
$rsa->loadKey($_SESSION["privatekey"]);
$message = $_POST["unityResponse"];
$ciphertext = base64_decode($message);
$this->payload->message = $rsa->decrypt($ciphertext);
Return "Decryption error in..." :(
I think general problem is in C#... Can you help me?
SOLVED!
By another way - XML key format
Server code:
$rsa = new Crypt_RSA();
$rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);
$rsa->setPrivateKeyFormat(CRYPT_RSA_PRIVATE_FORMAT_XML);
$rsa->setPublicKeyFormat(CRYPT_RSA_PUBLIC_FORMAT_XML);
$keys = $rsa->createKey(1024);
extract($keys);
$rsa->loadKey($publickey);
$_SESSION["privatekey"] = $privatekey;
$this->payload->publickey = $publickey;
Generate JSON:
{"publickey":"<RSAKeyValue>\r\n <Modulus>sCL/O7uUl4T32nUxZhKj1svDG88k4jkGsh/7IiFX/kTbj3mXmtYPLn5xTyLxEt9FxA/aoVxBmh1k7wA7lvcu5z4Avw6+AA/j793iDEhGdfvmXmHxm05xkjYO+LZ449YGDst9DUDO8SDA948Rld+eA187d/nhVPPAmun7RbLXBrs=</Modulus>\r\n <Exponent>AQAB</Exponent>\r\n</RSAKeyValue>"}
Unity Web Player code:
var N = JSON.Parse (generatedJSON);
var csp = new RSACryptoServiceProvider(1024);
csp.FromXmlString (N ["publickey"]);
var plainTextData = "Hello from Web Player";
var bytesPlainTextData = System.Text.Encoding.Unicode.GetBytes(plainTextData);
var bytesCypherText = csp.Encrypt(bytesPlainTextData, false);
var cypherText = Convert.ToBase64String(bytesCypherText);
And finally Server Decryption:
$rsa = new Crypt_RSA();
$rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);
$rsa->setPrivateKeyFormat(CRYPT_RSA_PRIVATE_FORMAT_XML);
$rsa->setPublicKeyFormat(CRYPT_RSA_PUBLIC_FORMAT_XML);
$rsa->loadKey($_SESSION["privatekey"]);
$cypherText= $_POST["cypherText"];
$bytesCipherText = base64_decode($message);
$this->payload->encrypted = $rsa->decrypt($bytesCipherText);
And you get JSON:
{"message":"Hello from Web Player"}
Thanks for perfect phpsec library! Its epic!
I share my example Unity project here. Hoping that it is useful to some people ;)
GitHub: unity-php-secure-communication
<?php
<?php
/**
* test with curl:
*
* // Generate keypair : return XML public key
* curl -c cookies.txt -d "keygen=1" http://exemple.com//encrypt.php
*
* // Test encrypt/decrypt : return encrypted and decrypted `my text to encode`
* curl -b cookies.txt -d "test=my text to encode" http://exemple.com//encrypt.php
*
* // Test encrypt : return encrypted
* curl -b cookie.txt -d "encrypt=my text to encode" http://exemple.com//encrypt.php > encrypted.txt; cat encrypted.txt
*
* // Test decrypt : return decrypted `my text to encode`
* curl -b cookie.txt -d "decrypt=`cat encrypted.txt`" http://exemple.com//encrypt.php
*/
include 'vendor/autoload.php';
use phpseclib\Crypt\RSA;
function generateKeyPair(){
if (!isset($_SESSION['publickey'])){
$rsa = new RSA();
$rsa->setPrivateKeyFormat(RSA::PRIVATE_FORMAT_XML);
$rsa->setPublicKeyFormat(RSA::PUBLIC_FORMAT_XML);
$keys = $rsa->createKey();
$_SESSION['privatekey'] = $keys['privatekey'];
$_SESSION['publickey'] = $keys['publickey'];
}
return $_SESSION['publickey'];
}
function encrypt($cleartext){
$rsa = new RSA();
$rsa->setEncryptionMode(RSA::ENCRYPTION_PKCS1);
$rsa->setPublicKeyFormat(RSA::PUBLIC_FORMAT_XML);
$rsa->loadKey($_SESSION['publickey']);
$bytesCipherText = $rsa->encrypt($cleartext);
return rawurlencode(base64_encode($bytesCipherText));
}
function decrypt($encrypted){
$rsa = new RSA();
$rsa->setEncryptionMode(RSA::ENCRYPTION_PKCS1);
$rsa->setPrivateKeyFormat(RSA::PRIVATE_FORMAT_XML);
$rsa->loadKey($_SESSION['privatekey']);
$bytesCipherText = base64_decode(rawurldecode($encrypted));
return $rsa->decrypt($bytesCipherText);
}
if (isset($_POST['session_id'])) {
session_id($_POST['session_id']);
}
session_start();
if (isset($_POST['keygen'])) {
echo generateKeyPair();
exit();
}
if (isset($_POST['encrypt'])) {
echo encrypt($_POST['encrypt']);
exit();
}
if (isset($_POST['decrypt'])) {
echo decrypt($_POST['decrypt']);
exit();
}
if (isset($_POST['test'])) {
generateKeyPair();
$ciphertext = encrypt($_POST['test']);
echo "encrypted: $ciphertext\n\n";
$clearText = decrypt($ciphertext);
echo "decrypted: $clearText\n";
exit();
}
using System;
using System.Collections;
using System.Security.Cryptography;
using System.Text;
using UnityEngine;
using UnityEngine.Analytics;
using UnityEngine.Networking;
using UnityEngine.UI;
public class EncryptController : MonoBehaviour
{
public string ScriptUrl = "http://example.com/encrypt.php";
public InputField ClearTextInputField;
public InputField EncryptedTextInputField;
public InputField ClearResponseInputField;
public Text SessionIdText;
public Text PublicKeyText;
public void OnKeygenButtonClick()
{
StartCoroutine(GenerateRsaKeyPair());
}
public void OnEncryptButtonClick()
{
if (PublicKeyText.text.Length < 100)
{
Debug.LogError("You must generate RSA key pair before");
return;
}
var csp = new RSACryptoServiceProvider(1024);
csp.FromXmlString(PublicKeyText.text);
var plainTextData = ClearTextInputField.text;
var bytesPlainTextData = Encoding.Unicode.GetBytes(plainTextData);
var bytesCypherText = csp.Encrypt(bytesPlainTextData, false);
var cypherText = Convert.ToBase64String(bytesCypherText);
EncryptedTextInputField.text = cypherText;
}
public void OnDecryptButtonClick()
{
if (PublicKeyText.text.Length < 100)
{
Debug.LogError("You must generate RSA key pair before");
return;
}
StartCoroutine(SendEncryptedText(EncryptedTextInputField.text));
}
IEnumerator GenerateRsaKeyPair()
{
var form = new WWWForm();
form.AddField("keygen", 1);
form.AddField("session_id", AnalyticsSessionInfo.sessionId.ToString());
SessionIdText.text = "sessionId=" + AnalyticsSessionInfo.sessionId.ToString();
using (var www = UnityWebRequest.Post(ScriptUrl, form))
{
yield return www.SendWebRequest();
if (www.isNetworkError)
{
Debug.LogError(www.error);
}
else
{
LogHeaders(www);
Debug.Log(www.downloadHandler.text);
PublicKeyText.text = www.downloadHandler.text;
}
}
}
IEnumerator SendEncryptedText(string text)
{
var form = new WWWForm();
form.AddField("decrypt", text);
form.AddField("session_id", AnalyticsSessionInfo.sessionId.ToString());
SessionIdText.text = "sessionId=" + AnalyticsSessionInfo.sessionId.ToString();
using (var www = UnityWebRequest.Post(ScriptUrl, form))
{
//www.SetRequestHeader("cookie", SessionIdText.text);
yield return www.SendWebRequest();
if (www.isNetworkError)
{
Debug.LogError(www.error);
}
else
{
LogHeaders(www);
// Print Body
Debug.Log(www.downloadHandler.text);
ClearResponseInputField.text = www.downloadHandler.text;
}
}
}
private void LogHeaders(UnityWebRequest www)
{
var sb = new StringBuilder();
foreach (var dict in www.GetResponseHeaders())
{
sb.Append(dict.Key).Append(": \t[").Append(dict.Value).Append("]\n");
if (dict.Key == "Set-Cookie")
{
SessionIdText.text = dict.Value + " (from response headers)";
}
}
Debug.Log(sb.ToString());
}
}
I need to convert this pice of PHP code to swift to create hashes, I am using a hash pattern in PHP to hash 2 strings with SHA256 and I would like to do this in swift, any ideas?
The SELF::SECRET is a secret key, and the SELF::HASH_PATTERN is my pattern and looks something like this: "00101010011100001010"
public function hash($first, $second) {
// Append the secret to the values.
$first = self::SECRET . $first;
$second = $second . self::SECRET;
// Hash the values.
$hash = hash_init('sha256');
hash_update($hash, $first);
$hash1 = hash_final($hash);
$hash = hash_init('sha256');
hash_update($hash, $second);
$hash2 = hash_final($hash);
// Create a new hash with pieces of the two we just made.
$result = '';
for ($i = 0; $i < strlen(self::HASH_PATTERN); $i++) {
$result .= substr(self::HASH_PATTERN, $i, 1) ? $hash2[$i] : $hash1[$i];
}
return $result;
}
Thanks!
UPDATE:
This is the part which I can't figure out:
$hash = hash_init('sha256');
hash_update($hash, $first);
$hash1 = hash_final($hash);
UPDATE:
After a few hours of doing research and coding I finally got it figured out.
This is the code that I wrote, maybe not the best, but it works :)
I used a small class from github for generating SHA256 strings in swift called NSHash
func create_token(first:String, second:String) -> String {
var newFirst = constants.secret + first as NSString
var newSecond = second + constants.secret as NSString
var hash1 = newFirst.SHA256()
var hash2 = newSecond.SHA256()
var result = ""
for var i = 0; i < countElements(constants.hash_pattern); i++ {
var character = "\(constants.hash_pattern[i])" as String
var number:Int = character.toInt()!
if number == 1 {
result = "\(result)\(hash2[i])"
}else {
result = "\(result)\(hash1[i])"
}
}
return result
}