Generate your form by clearing the Response and rewriting the html HTTP form out into the cleared response. When I get home I will trawl through my old code and provide an example.
EDIT:
OK here is my code, I had to recreate because I am still at work but it goes a little like this:
Create an intermediate page to capture your variables from the ASPX page and then use this to send as a 'simple' form:
protected void Page_Load(object sender, EventArgs e)
{
// Capture the post to this page
IDictionary<string, string> variables = new Dictionary<string, string>();
variables.Add("test", Request.Form["test"]); // collect all variables after checking they exist
RewriteContent(variable);
}
public void RewriteContent(IDictionary<string, string> variables)
{
string formContent = @"
<html>
<head>
<title>My Form</title>
</head>
<body>
<form action='' method=''>";
foreach (KeyValuePair<string, string> keyVal in variables)
{
formContent += @"<input type='" + keyVal.Key + "' value='" + keyVal.Value + "' />";
}
formContent += @"
</form>
</body>
</html>"; // Add either an auto post in a javascript or an explicit submit button
Response.Clear();
Response.Write(formContent);
Response.Flush();
Response.End();
}
EDIT 2:
Sorry I just realised I have not answered the other questions.
Q3/Q4/Q5. If you are not using https you cannot really stop tampering or be sure the response is correct but you can restrict the chance it is bogus. This can be achieved by hashing the values with a secret that is shared at your end and the destination, and then when you get the response you should hash the values and compare to the hash that is sent back to you before you accept that it is valid.
Most payment mechanisms are verified in this manner usually with an MD5 or SHA1 hash you can find more info on the following links:
http://msdn.microsoft.com/en-us/library/system.security.cryptography.sha1.aspx
http://www.developerfusion.com/code/4601/create-hashes-md5-sha1-sha256-sha384-sha512/
http://snippets.dzone.com/posts/show/5816
EDIT 3:
Doing some encryption now and thought I would share some code with you (because I am nice like that). Might give you an idea of what to do and you can probably code better than me so just tidy up my mess a bit :)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
using log4net;
namespace MyCompany.Cipher
{
private static readonly ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
public string GenerateSha1HashForString(string valueToHash, EncodeStyle encodeStyle)
{
string hashedString = string.Empty;
try
{
hashedString = SHA1HashEncode(Encoding.UTF8.GetBytes(valueToHash), encodeStyle);
}
catch (Exception ex)
{
if (log.IsErrorEnabled) { log.Error(string.Format("{0}\r\n{1}", ex.Message, ex.StackTrace)); }
throw new Exception("Error trying to hash a string; information can be found in the error log", ex);
}
return hashedString;
}
private string ByteArrayToString(byte[] bytes, EncodeStyle encodeStyle)
{
StringBuilder output = new StringBuilder(bytes.Length);
if (EncodeStyle.Base64 == encodeStyle)
{
return Convert.ToBase64String(bytes);
}
for (int i = 0; i < bytes.Length; i++)
{
switch (encodeStyle)
{
case EncodeStyle.Dig:
//encode to decimal with 3 digits so 7 will be 007 (as range of 8 bit is 127 to -128)
output.Append(bytes[i].ToString("D3"));
break;
case EncodeStyle.Hex:
output.Append(bytes[i].ToString("X2"));
break;
}
}
return output.ToString();
}
private string SHA1HashEncode(byte[] valueToHash, EncodeStyle encode)
{
SHA1 a = new SHA1CryptoServiceProvider();
byte[] arr = new byte[60];
string hash = string.Empty;
arr = a.ComputeHash(valueToHash);
hash = ByteArrayToString(arr, encode);
return hash;
}
}
Put it in a class some where that your project can see and it can generate an SHA1 hash based on a string value by calling the public method.