Generating the Single Sign-on Authentication Token using C#
Mapping a User using SuiteTalk sample using C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NetSuiteAuthToken.NetSuiteServiceReference2011_2;
using System.Security.Cryptography;
using System.IO;
using Mono.Math;
namespace NetSuiteAuthToken
{
class Program
{
static void Main(string[] args)
{
NetSuitePortType port = new NetSuitePortTypeClient();
SsoCredentials ssoCreds = new SsoCredentials();
String mappingString = "<NS USER MAPPING STRING>";
String nsuseremail = "<NS USER EMAIL>";
String password = "<NS PASSWORD>";
String NSAccountID = "<NS ACCOUNT ID>";
String partnerID = "<Partner ID>";
String privateKeyPath = "<Private KEY Path>";
ssoCreds.email = nsuseremail;
ssoCreds.password = password;
ssoCreds.account = NSAccountID;
ssoCreds.partnerId = partnerID;
RecordRef recordRef = new RecordRef();
recordRef.internalId = "3";
ssoCreds.role = recordRef;
String authToken = createAuthToken(NSAccountID, mappingString, privateKeyPath);
Console.WriteLine("Auth Token: " + authToken);
ssoCreds.authenticationToken = authToken.Trim();
mapSsoRequest ssoReq = new mapSsoRequest();
ssoReq.ssoCredentials = ssoCreds;
ssoReq.partnerInfo = new PartnerInfo();
ssoReq.applicationInfo = new ApplicationInfo();
mapSsoResponse ssoRes = null;
ssoRes = port.mapSso(ssoReq);
Console.WriteLine("Status: " + ssoRes.sessionResponse.status.isSuccess);
Console.WriteLine("userId: " + ssoRes.sessionResponse.userId.name);
Console.Read();
}
static String createAuthToken(String NSAccountID, String mappingString, String privateKeyPath)
{
String authToken = "";
RSAParameters rsaParam = DecodeRSAPrivateKey(GetFileBytes(privateKeyPath));
byte[] encryptedBytes;
double millis = (DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalMilliseconds;
String millisStr = (millis + "");
millisStr = millisStr.Substring(0, millisStr.Length - (millisStr.Length - millisStr.IndexOf('.')));
String plainText = NSAccountID + " " + mappingString + " " + millisStr;
byte[] toEncrypt = StrToByteArray(plainText.Trim());
encryptedBytes = privateEncrypt(toEncrypt, rsaParam);
authToken = ByteToStr(encryptedBytes);
return authToken;
}
public static byte[] privateEncrypt(byte[] toEncrypt, RSAParameters rsaParam)
{
BigInteger modulus = new BigInteger(rsaParam.Modulus);
int modLength = getSignificantLength(rsaParam.Modulus);
BigInteger D = new BigInteger(rsaParam.D);
BigInteger data = new BigInteger(pkcs1PrivPad(toEncrypt, modLength));
byte[] encrypted = zeroPad(data.ModPow(D, modulus).GetBytes(), modLength);
return encrypted;
}
private static byte[] zeroPad(byte[] raw, int modLength)
{
byte[] returnMe = new byte[modLength];
int srcStart = Math.Max(raw.Length - modLength, 0);
int dstStart = Math.Max(0, modLength - raw.Length);
int length = Math.Min(modLength, raw.Length);
Array.Copy(raw, srcStart, returnMe, dstStart, length);
for (int i = 0; i < modLength - raw.Length; i++) { returnMe[i] = 0; };
return returnMe;
}
private static int getSignificantLength(byte[] raw)
{
int i = 0;
while (raw[i] == 0) { i++; };
return raw.Length - i;
}
private static byte[] pkcs1PrivPad(byte[] raw, int modLength)
{
MemoryStream os = new MemoryStream();
int padLength = modLength - raw.Length;
if (padLength < 11) return raw;
os.WriteByte(0);
os.WriteByte(1);
for (int i = 2; i < padLength - 1; i++)
{
os.WriteByte(0xFF);
}
os.WriteByte(0);
os.Write(raw, 0, raw.Length);
return os.ToArray();
}
private static byte[] GetFileBytes(String filename)
{
if (!System.IO.File.Exists(filename))
return null;
Stream stream = new FileStream(filename, FileMode.Open);
int datalen = (int)stream.Length;
byte[] filebytes = new byte[datalen];
stream.Seek(0, SeekOrigin.Begin);
stream.Read(filebytes, 0, datalen);
stream.Close();
return filebytes;
}
public static byte[] StrToByteArray(string str)
{
return System.Text.Encoding.UTF8.GetBytes(str);
}
public static String ByteToStr(byte[] bytes)
{
String hex = BitConverter.ToString(bytes);
hex = hex.Replace("-", "");
return hex;
}
public static RSAParameters DecodeRSAPrivateKey(byte[] privkey)
{
byte[] MODULUS, E, D, P, Q, DP, DQ, IQ;
MemoryStream mem = new MemoryStream(privkey);
BinaryReader binr = new BinaryReader(mem);
RSAParameters RSAparams = new RSAParameters();
byte bt = 0;
ushort twobytes = 0;
int elems = 0;
try
{
twobytes = binr.ReadUInt16();
if (twobytes == 0x8130)
{
binr.ReadByte();
}
else if (twobytes == 0x8230)
{
binr.ReadInt16();
}
else
{
return RSAparams;
}
twobytes = binr.ReadUInt16();
if (twobytes != 0x0102)
return RSAparams;
bt = binr.ReadByte();
if (bt != 0x00)
return RSAparams;
elems = GetIntegerSize(binr);
MODULUS = binr.ReadBytes(elems);
elems = GetIntegerSize(binr);
E = binr.ReadBytes(elems);
elems = GetIntegerSize(binr);
D = binr.ReadBytes(elems);
RSAparams.Modulus = MODULUS;
RSAparams.Exponent = E;
RSAparams.D = D;
return RSAparams;
}
catch (Exception)
{
return RSAparams;
}
finally { binr.Close(); }
}
private static int GetIntegerSize(BinaryReader binr)
{
byte bt = 0;
byte lowbyte = 0x00;
byte highbyte = 0x00;
int count = 0;
bt = binr.ReadByte();
if (bt != 0x02)
return 0;
bt = binr.ReadByte();
if (bt == 0x81)
{
count = binr.ReadByte();
}
else
if (bt == 0x82)
{
highbyte = binr.ReadByte();
lowbyte = binr.ReadByte();
byte[] modint = { lowbyte, highbyte, 0x00, 0x00 };
count = BitConverter.ToInt32(modint, 0);
}
else
{
count = bt;
}
while (binr.ReadByte() == 0x00)
{
count -= 1;
}
binr.BaseStream.Seek(-1, SeekOrigin.Current);
return count;
}
}
}
Used C# BigInteger Class by Chew Keong TAN
http://www.codeproject.com/Articles/2728/C-BigInteger-Class
No comments:
Post a Comment