initial checkin of yaulw (locally)
This commit is contained in:
482
@integrate/CheckActiveTwo.cs
Normal file
482
@integrate/CheckActiveTwo.cs
Normal file
@@ -0,0 +1,482 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
using System.Text;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace PhoneHome
|
||||
{
|
||||
internal class CheckActiveTwo
|
||||
{
|
||||
internal string ProductName = String.Empty;
|
||||
internal string ProductVersion = String.Empty;
|
||||
internal string SerialNumber = String.Empty;
|
||||
private string _LastGeneratedKey = String.Empty;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="ProductName"></param>
|
||||
/// <param name="ProductVersion"></param>
|
||||
/// <param name="SerialNumber"></param>
|
||||
internal CheckActiveTwo(string ProductName, string ProductVersion, string SerialNumber)
|
||||
{
|
||||
if (!String.IsNullOrEmpty(ProductName) && !String.IsNullOrEmpty(ProductVersion) && !String.IsNullOrEmpty(SerialNumber))
|
||||
{
|
||||
this.ProductName = ProductName;
|
||||
this.ProductVersion = ProductVersion;
|
||||
this.SerialNumber = SerialNumber;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ArgumentException("ProductName, ProductVersion, and SerialNumber can't be blank");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="strEncGeneratedString"></param>
|
||||
internal CheckActiveTwo(string strEncGeneratedString)
|
||||
{
|
||||
if (IsValidEncKey(strEncGeneratedString))
|
||||
{
|
||||
_LastGeneratedKey = strEncGeneratedString;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ArgumentException("Not a valid Enc String");
|
||||
}
|
||||
}
|
||||
|
||||
#region Static Internal Utilities
|
||||
|
||||
/// <summary>
|
||||
/// Perform checksum on string
|
||||
/// </summary>
|
||||
/// <param name="strAboutToBeChecksummed"></param>
|
||||
/// <returns>Checksum</returns>
|
||||
internal static int PerformChecksum(string strAboutToBeChecksummed)
|
||||
{
|
||||
if (!String.IsNullOrEmpty(strAboutToBeChecksummed))
|
||||
{
|
||||
int nChecksum = 0;
|
||||
for (int i = 0; i < strAboutToBeChecksummed.Length; ++i)
|
||||
{
|
||||
if (Char.IsDigit(strAboutToBeChecksummed[i]))
|
||||
nChecksum = nChecksum + int.Parse(strAboutToBeChecksummed[i].ToString());
|
||||
}
|
||||
return nChecksum;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dash a String
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
internal static string MakeIntoDashSeperatedString(string strAboutToBeDashed, int DashEveryNthCharacter)
|
||||
{
|
||||
if (!String.IsNullOrEmpty(strAboutToBeDashed))
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < strAboutToBeDashed.Length; i++)
|
||||
{
|
||||
if ((i != 0) && ((i % DashEveryNthCharacter) == 0))
|
||||
sb.Append("-");
|
||||
sb.Append(strAboutToBeDashed[i]);
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
return String.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Undash a String
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
internal static string MakeIntoDashUnseperatedString(string strAboutToBeUndashed)
|
||||
{
|
||||
if (!String.IsNullOrEmpty(strAboutToBeUndashed))
|
||||
return strAboutToBeUndashed.Replace("-", "");
|
||||
return String.Empty;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Internal Methods
|
||||
|
||||
/// <summary>
|
||||
/// Generate a new Key to use - the key can be used to verify the serial number
|
||||
/// </summary>
|
||||
/// <returns>a new Key</returns>
|
||||
internal string GenerateNewKey()
|
||||
{
|
||||
// GenerateString For User to send
|
||||
string KeyValue = MakeKey();
|
||||
string EncrKey = EncodeShuffle(KeyValue);
|
||||
_LastGeneratedKey = MakeIntoDashSeperatedString(EncrKey, 4);
|
||||
|
||||
// For Debugging
|
||||
string UnEncoded = DecodeShuffle(EncrKey);
|
||||
if (KeyValue != UnEncoded)
|
||||
{
|
||||
// something is terribly wrong with the Encryption
|
||||
Debug.Assert(false);
|
||||
}
|
||||
return _LastGeneratedKey;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The function should really be called 'GeneratedPIN' but for reverse engineering
|
||||
/// purpose, keeping them guessin * security by obscurity *
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
internal string GeneraledPiM()
|
||||
{
|
||||
if (!String.IsNullOrEmpty(_LastGeneratedKey))
|
||||
{
|
||||
int KeyChecksum = PerformChecksum(MakeKey());
|
||||
int ShuffledChecksum = PerformChecksum(_LastGeneratedKey);
|
||||
string Result = KeyChecksum.ToString() + ShuffledChecksum.ToString();
|
||||
if (Result.Length < 4)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder(Result);
|
||||
int nRemainder = 4 - Result.Length;
|
||||
while (nRemainder > 0) { sb.Append("7"); nRemainder--; }
|
||||
Result = sb.ToString();
|
||||
}
|
||||
Result = Result.Substring(0, 4);
|
||||
int nHour = DateTime.Now.ToUniversalTime().Hour;
|
||||
nHour = (nHour <= 6) ? (nHour + 3) : (nHour - 2);
|
||||
string strHour = String.Format("{0}", (nHour < 10) ? ("8" + nHour.ToString()) : (nHour.ToString()));
|
||||
string fourdigitPin = (strHour[1] + Result[1].ToString() + strHour[0] + Result[3].ToString());
|
||||
int nChecksumPin = PerformChecksum(fourdigitPin);
|
||||
string strChecksumLastDigit = nChecksumPin.ToString()[nChecksumPin.ToString().Length - 1].ToString();
|
||||
return fourdigitPin + strChecksumLastDigit;
|
||||
}
|
||||
else
|
||||
{
|
||||
GenerateNewKey();
|
||||
return GeneraledPiM();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="dtStamp"></param>
|
||||
/// <param name="ProductName"></param>
|
||||
/// <param name="ProductVersion"></param>
|
||||
/// <param name="SerialNumber"></param>
|
||||
/// <returns>true, if successful, false otherwise</returns>
|
||||
internal bool RetrieveValues(out DateTime dtStamp, out string ProductName, out string ProductVersion, out string SerialNumber)
|
||||
{
|
||||
dtStamp = DateTime.MinValue;
|
||||
ProductName = String.Empty;
|
||||
ProductVersion = String.Empty;
|
||||
SerialNumber = String.Empty;
|
||||
if (!String.IsNullOrEmpty(_LastGeneratedKey))
|
||||
{
|
||||
string Undashed = MakeIntoDashUnseperatedString(_LastGeneratedKey);
|
||||
if (UnmakeKey(DecodeShuffle(Undashed), out dtStamp, out ProductName, out ProductVersion, out SerialNumber))
|
||||
{
|
||||
this.ProductName = ProductName;
|
||||
this.ProductVersion = ProductVersion;
|
||||
this.SerialNumber = SerialNumber;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private Key Generation Functions
|
||||
|
||||
private bool ContainsOnlyDigits(string strToCheckForDigits)
|
||||
{
|
||||
if (!String.IsNullOrEmpty(strToCheckForDigits))
|
||||
{
|
||||
for (int i = 0; i < strToCheckForDigits.Length; ++i)
|
||||
{
|
||||
if (!Char.IsDigit(strToCheckForDigits[i]))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check to see if the Generated string being passed in is a valid generated string
|
||||
/// </summary>
|
||||
/// <param name="strGeneratedString"></param>
|
||||
/// <returns>true if valid, false otherwise</returns>
|
||||
private bool IsValidEncKey(string strEncGeneratedString)
|
||||
{
|
||||
string Undashed = MakeIntoDashUnseperatedString(strEncGeneratedString);
|
||||
DateTime dt;
|
||||
string pName, pVersion, pSerial;
|
||||
if (UnmakeKey(DecodeShuffle(Undashed), out dt, out pName, out pVersion, out pSerial))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Make a Key to send across (all the info the auth needs)
|
||||
/// </summary>
|
||||
/// <returns>Key with needed Info</returns>
|
||||
private string MakeKey()
|
||||
{
|
||||
//string dtShortTest = DateTime.Now.ToUniversalTime().ToShortDateString().Replace("/", "");
|
||||
DateTime dtUniversal = DateTime.Now.ToUniversalTime();
|
||||
string dtMonth = (dtUniversal.Month > 9) ? String.Format("{0}", dtUniversal.Month) : String.Format("0{0}", dtUniversal.Month);
|
||||
string dtDay = (dtUniversal.Day > 9) ? String.Format("{0}", dtUniversal.Day) : String.Format("0{0}", dtUniversal.Day);
|
||||
string dtYear = dtUniversal.Year.ToString();
|
||||
string dtShort = String.Format("{0}{1}{2}", dtMonth, dtDay, dtYear);
|
||||
string ProductId = ProductName.Substring(0, 1); // should always be 'M' or 'L' // so we use "LMXYZ"
|
||||
string strKey = dtShort + "Z" + ProductId + "Y" + ProductVersion.Split('.')[0] + "X" + SerialNumber;
|
||||
return strKey;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unmake a key * Don't even know why i wrote this, prob. won't end up using this *
|
||||
/// </summary>
|
||||
/// <returns>true if successful, false otheriwise</returns>
|
||||
private bool UnmakeKey(string strAboutToBeUnkeyed, out DateTime dtStamp, out string ProductName, out string ProductVersion, out string SerialNumber)
|
||||
{
|
||||
dtStamp = DateTime.MinValue;
|
||||
ProductName = "";
|
||||
ProductVersion = "";
|
||||
SerialNumber = "";
|
||||
|
||||
//string strKey = dtShort + "Z" + ProductId + "Y" + ProductVersion.Split('.')[0] + "X" + SerialNumber;
|
||||
//0123456Z
|
||||
try
|
||||
{
|
||||
if (!String.IsNullOrEmpty(strAboutToBeUnkeyed))
|
||||
{
|
||||
int nZIndex = strAboutToBeUnkeyed.IndexOf("Z");
|
||||
int nYIndex = strAboutToBeUnkeyed.IndexOf("Y");
|
||||
int nXIndex = strAboutToBeUnkeyed.IndexOf("X");
|
||||
if (nZIndex == -1 || nYIndex == -1 || nXIndex == -1)
|
||||
return false;
|
||||
|
||||
// dtShort
|
||||
string strDT = strAboutToBeUnkeyed.Substring(0, nZIndex);
|
||||
strDT = String.Format("{0}/{1}/{2}", strDT.Substring(0, 2), strDT.Substring(2, 2), strDT.Substring(4));
|
||||
dtStamp = DateTime.Parse(strDT);
|
||||
|
||||
// ProductId
|
||||
string ProductId = strAboutToBeUnkeyed.Substring(nZIndex + 1, 1);
|
||||
if (ProductId == "L")
|
||||
ProductName = "Lytec";
|
||||
else if (ProductId == "M")
|
||||
ProductName = "Medisoft";
|
||||
else
|
||||
return false;
|
||||
|
||||
// ProductVersion
|
||||
string strProductVersion = strAboutToBeUnkeyed.Substring(nYIndex + 1, (nXIndex - nYIndex - 1));
|
||||
if (!String.IsNullOrEmpty(strProductVersion) && ContainsOnlyDigits(strProductVersion))
|
||||
ProductVersion = strProductVersion;
|
||||
else
|
||||
return false;
|
||||
|
||||
// Serial Number
|
||||
SerialNumber = strAboutToBeUnkeyed.Substring(nXIndex + 1);
|
||||
return !String.IsNullOrEmpty(SerialNumber) && ContainsOnlyDigits(SerialNumber);
|
||||
}
|
||||
}
|
||||
catch (Exception) { /* ignore */ }
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// * Simple Encoder *
|
||||
/// </summary>
|
||||
/// <param name="strAboutToBeEncodeShuffled"></param>
|
||||
/// <returns></returns>
|
||||
private string EncodeShuffle(string strAboutToBeEncodeShuffled)
|
||||
{
|
||||
const string Char_CodeLib = "ABCDEFGHIJKNOPQRSTUVW"; //20 - W is never used
|
||||
const string Char_CodeLibExcluded = "LMXYZ"; //5
|
||||
|
||||
if (!String.IsNullOrEmpty(strAboutToBeEncodeShuffled))
|
||||
{
|
||||
List<char> ResultStr = new List<char>(strAboutToBeEncodeShuffled);
|
||||
int nCount = ResultStr.Count;
|
||||
|
||||
// Every N'th Digit do something
|
||||
for (int i = 0; i < nCount; i = i + 3)
|
||||
{
|
||||
char c = ResultStr[i];
|
||||
if (char.IsDigit(c))
|
||||
{
|
||||
int nChar = int.Parse(c.ToString());
|
||||
ResultStr[i] = Char_CodeLib[nChar]; // 0..9
|
||||
}
|
||||
}
|
||||
|
||||
// Every N'th Digit do something
|
||||
for (int i = 0; i < nCount; i = i + 4)
|
||||
{
|
||||
char c = ResultStr[i];
|
||||
if (char.IsDigit(c))
|
||||
{
|
||||
int nChar = int.Parse(c.ToString());
|
||||
ResultStr[i] = Char_CodeLib[nChar + 10]; // 10..19
|
||||
}
|
||||
}
|
||||
|
||||
// Add Randomness to the end of the string
|
||||
Random random = new Random();
|
||||
int nRand = random.Next(1, 9);
|
||||
|
||||
// Perform a Random Shift * So that the code ALWAYS looks different from use to use *
|
||||
for (int i = 0; i < nCount; i = i + 2)
|
||||
{
|
||||
char c = ResultStr[i];
|
||||
if (char.IsLetter(c) && !Char_CodeLibExcluded.Contains(c.ToString()))
|
||||
{
|
||||
int nIndexShifted = Char_CodeLib.IndexOf(c) + nRand;
|
||||
int nIndexShiftedAdj = nIndexShifted % 21;
|
||||
ResultStr[i] = Char_CodeLib[nIndexShiftedAdj]; // 0..20
|
||||
}
|
||||
}
|
||||
|
||||
// Perform another Random Swap * So that the code ALWAYS looks different from use to use *
|
||||
for (int i = 0; i < nCount; i = i + nRand)
|
||||
{
|
||||
char c = ResultStr[i];
|
||||
int nOpposite = nCount - i - 1;
|
||||
char o = ResultStr[nOpposite];
|
||||
if (char.IsLetter(c) && !Char_CodeLibExcluded.Contains(c.ToString()) &&
|
||||
char.IsLetter(o) && !Char_CodeLibExcluded.Contains(o.ToString()))
|
||||
{
|
||||
// swap
|
||||
ResultStr[i] = o;
|
||||
ResultStr[nOpposite] = c;
|
||||
}
|
||||
}
|
||||
|
||||
// Perform a Reversal
|
||||
for (int i = 0; i < (nCount / 2); ++i)
|
||||
{
|
||||
char N1 = ResultStr[i];
|
||||
char N2 = ResultStr[nCount - 1 - i];
|
||||
// swap
|
||||
ResultStr[i] = N2;
|
||||
ResultStr[nCount - 1 - i] = N1;
|
||||
}
|
||||
|
||||
// Add the Randomness to the string for proper decoding to occur
|
||||
ResultStr.Add(Char.Parse(nRand.ToString()));
|
||||
|
||||
// And Return
|
||||
return new String(ResultStr.ToArray());
|
||||
}
|
||||
return String.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// * Simple Decoder *
|
||||
/// </summary>
|
||||
/// <param name="strAboutToBeDecodeShuffled"></param>
|
||||
/// <returns></returns>
|
||||
private string DecodeShuffle(string strAboutToBeDecodeShuffled)
|
||||
{
|
||||
const string Char_CodeLib = "ABCDEFGHIJKNOPQRSTUVW"; //20
|
||||
const string Char_CodeLibExcluded = "LMXYZ"; //5
|
||||
try
|
||||
{
|
||||
if (!String.IsNullOrEmpty(strAboutToBeDecodeShuffled))
|
||||
{
|
||||
List<char> ResultStr = new List<char>(strAboutToBeDecodeShuffled);
|
||||
|
||||
// retrieve Randomness Factor
|
||||
char cLast = ResultStr[ResultStr.Count - 1];
|
||||
ResultStr.RemoveAt(ResultStr.Count - 1);
|
||||
int nCount = ResultStr.Count;
|
||||
int nRand = int.Parse(cLast.ToString());
|
||||
|
||||
// Perform a Reversal
|
||||
for (int i = 0; i < (nCount / 2); ++i)
|
||||
{
|
||||
char N1 = ResultStr[i];
|
||||
char N2 = ResultStr[nCount - 1 - i];
|
||||
// swap
|
||||
ResultStr[i] = N2;
|
||||
ResultStr[nCount - 1 - i] = N1;
|
||||
}
|
||||
|
||||
// Perform another Random Swap * So that the code ALWAYS looks different from use to use *
|
||||
for (int i = 0; i < nCount; i = i + nRand)
|
||||
{
|
||||
char c = ResultStr[i];
|
||||
int nOpposite = nCount - i - 1;
|
||||
char o = ResultStr[nOpposite];
|
||||
if (char.IsLetter(c) && !Char_CodeLibExcluded.Contains(c.ToString()) &&
|
||||
char.IsLetter(o) && !Char_CodeLibExcluded.Contains(o.ToString()))
|
||||
{
|
||||
// swap
|
||||
ResultStr[i] = o;
|
||||
ResultStr[nOpposite] = c;
|
||||
}
|
||||
}
|
||||
|
||||
// Perform a Random Shift * So that the code ALWAYS looks different from use to use *
|
||||
for (int i = 0; i < nCount; i = i + 2)
|
||||
{
|
||||
char c = ResultStr[i];
|
||||
if (char.IsLetter(c) && !Char_CodeLibExcluded.Contains(c.ToString()))
|
||||
{
|
||||
int nIndexShifted = Char_CodeLib.IndexOf(c) - nRand;
|
||||
int nIndexShiftedAdj = (nIndexShifted < 0)? 21 + nIndexShifted : nIndexShifted;
|
||||
|
||||
ResultStr[i] = Char_CodeLib[nIndexShiftedAdj]; // 0..20
|
||||
}
|
||||
}
|
||||
|
||||
// Every N'th Digit do something
|
||||
for (int i = 0; i < nCount; i = i + 4)
|
||||
{
|
||||
char c = ResultStr[i];
|
||||
if (char.IsLetter(c) && !Char_CodeLibExcluded.Contains(c.ToString()))
|
||||
{
|
||||
int nIndex = Char_CodeLib.IndexOf(c);
|
||||
if (nIndex >= 10)
|
||||
{
|
||||
nIndex = nIndex - 10;
|
||||
if (nIndex >= 0 && nIndex <= 9)
|
||||
ResultStr[i] = Char.Parse(nIndex.ToString()); // 11..19
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Every N'th Digit do something
|
||||
for (int i = 0; i < nCount; i = i + 3)
|
||||
{
|
||||
char c = ResultStr[i];
|
||||
if (char.IsLetter(c))
|
||||
{
|
||||
int nIndex = Char_CodeLib.IndexOf(c);
|
||||
if (nIndex >= 0 && nIndex <= 9)
|
||||
ResultStr[i] = Char.Parse(nIndex.ToString()); // 1..9
|
||||
}
|
||||
}
|
||||
|
||||
// And Return
|
||||
return new String(ResultStr.ToArray());
|
||||
}
|
||||
}
|
||||
catch (Exception) { /* ignore */ }
|
||||
return String.Empty;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user