I have disabled sslv3 in server side like this :
char certPass[] = "***";
char certAliaMainPass[] = "***";;
KeyStore keyStore = KeyStore.getInstance("JKS");
keyStore.load(new FileInputStream(certPath), certPass);
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509");
keyManagerFactory.init(keyStore, certAliaMainPass);
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(keyManagerFactory.getKeyManagers(), null, null);
SSLServerSocketFactory sslServerSocketFactory = sslContext.getServerSocketFactory();
sslServerSocket = (SSLServerSocket) sslServerSocketFactory.createServerSocket(iPort);
String[] protocols = sslServerSocket.getEnabledProtocols();
Set<String> set = new HashSet<String>();
for (String s : protocols) {
if (s.equals("SSLv3")) {
continue;
}
set.add(s);
}
sslServerSocket.setEnabledProtocols(set.toArray(new String[0]));
but client which used "SSLv3" still can connect to server, how can I do for this issue?
Go to Java installation folder.
Open {JRE_HOME}\lib\security\java.security -file in text editor.
Go to the last line.
Delete or comment out the following line jdk.tls.disabledAlgorithms=SSLv3
Related
I'm struggeling a bit with my code to make it possible to use mTLS in the RESTClient. So I'm looking for a way to establish an mTLS connection. Here is my code:
...
def mymTLSservice = "https://my-token-service.example.com"
// Load custom my TrustStore and KeyStore
def pathToKeyStore = "/path/to/keystore.jceks"
def pathToTrustStore = "/path/to/truststore"
def keyStorePW = "myKeyStorePW"
def trustStorePW = "myTrustStorePW"
final char[] pwdKeyStore = keyStorePW.toCharArray()
final char[] pwdTrustStore = trustStorePW.toCharArray()
String keyAlias = "my-mTls-cert-alias" // If you have more than one key
String storeType = "JCEKS"
FileInputStream keyStoreInputStream = new FileInputStream(pathToKeyStore)
FileInputStream trustStoreInputStream = new FileInputStream(pathToTrustStore)
KeyStore ks = KeyStore.getInstance(storeType)
ks.load(keyStoreInputStream, pwdKeyStore)
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType())
trustStore.load(trustStoreInputStream, pwdTrustStore)
Key mTlsPrivateKey = ks.getKey(keyAlias, pwdKeyStore)
Certificate[] mTlsChain = ks.getCertificateChain(keyAlias)
KeyStore mtlsKeyStore = KeyStore.getInstance("jks")
mtlsKeyStore.load(null, null)
mtlsKeyStore.setKeyEntry(keyAlias, mTlsPrivateKey, pwdKeyStore, mTlsChain)
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509")
keyManagerFactory.init(mtlsKeyStore, pwdKeyStore)
TrustManagerFactory trustManagerFactory =
TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(trustStore);
// Create SSLContext
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(
keyManagerFactory.getKeyManagers(),
trustManagerFactory,
new java.security.SecureRandom());
SSLConnectionSocketFactory sf = new SSLConnectionSocketFactory(sc)
def http = new RESTClient(mymTLSservice)
http.auth.basic 'user', 'password'
// HOW CAN I ADD THE SSLConnectionSocketFactory here
http.handler.failure = { resp -> println "Failure: ${resp.statusLine}" }
// Trying request"
def access_token = ''
try{
http.get(
path : "/v2/token"
)
{ resp, json ->
access_token = json
println "access_token"
}
println resp
} catch(HttpResponseException e) {
r = e.response
println("Success: $r.success")
println("Status: $r.status")
println("Reason: $r.statusLine.reasonPhrase")
println("Could not retrieve an access token from token provider!")
}
How can I correctly add the SSLConnectionSocketFactory to http?
Thank you!
I'm trying to communicate over mTLS with a service.
After long investigation I finally figured it out. Hope it helps someone in the same situation.
In the above snippet we create an SSLContext "sc" which we need to pass to the new defined SSLSocketFactory "sf". Then we create a new "Scheme" definition which will use the newly created SSLSocketFactory "sf" for every "https" request. So the above line were we create a SSLConnectionSocketFactory has to replaced with SSLSocketFactory.
SSLSocketFactory sf = new SSLSocketFactory(sc);
Scheme httpsScheme = new Scheme("https", 443, sf);
And at the end we override the ConnectionManager of the RESTClient with the scheme definition "httpsScheme".
def http = new RESTClient(mymTLSservice)
http.auth.basic 'user', 'password'
http.client.connectionManager.schemeRegistry.register(httpsScheme) // this will add the custom keyStore to every https call
This will cause that during SSL negotiation a client certificate will be presented.
I would like to use the Microsft Graph API to get informations from the azure active directory. For this I need an access token, which is issued based on a secret or certificate.
In the azure portal the use of a certificate is recommended.
What are the reasons for using a certificate? Is the use of a certificate more secure than a secret?
What type of certificate can and should be stored? How can it be generated?
Many thanks in advance!
What are the reasons for using a certificate? Is the use of a
certificate more secure than a secret?
Yes, Certificate is more secure than Secret, thus it is more complex and more expensive.
You could refer to the link in silent's comment.
What type of certificate can and should be stored? How can it be
generated?
File Type: .cer, .pem, .crt
Read details about the format of certificate. Here is how to craft a signed client assertion:
string Encode(byte[] arg)
{
char Base64PadCharacter = '=';
char Base64Character62 = '+';
char Base64Character63 = '/';
char Base64UrlCharacter62 = '-';
char Base64UrlCharacter63 = '_';
string s = Convert.ToBase64String(arg);
s = s.Split(Base64PadCharacter)[0]; // RemoveAccount any trailing padding
s = s.Replace(Base64Character62, Base64UrlCharacter62); // 62nd char of encoding
s = s.Replace(Base64Character63, Base64UrlCharacter63); // 63rd char of encoding
return s;
}
string GetSignedClientAssertion()
{
//Signing with SHA-256
string rsaSha256Signature = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256";
X509Certificate2 certificate = new X509Certificate2("Certificate.pfx", "Password", X509KeyStorageFlags.EphemeralKeySet);
//Create RSACryptoServiceProvider
var x509Key = new X509AsymmetricSecurityKey(certificate);
var privateKeyXmlParams = certificate.PrivateKey.ToXmlString(true);
var rsa = new RSACryptoServiceProvider();
rsa.FromXmlString(privateKeyXmlParams);
//alg represents the desired signing algorithm, which is SHA-256 in this case
//kid represents the certificate thumbprint
var header = new Dictionary<string, string>()
{
{ "alg", "RS256"},
{ "kid", Encode(Certificate.GetCertHash()) }
};
//Please see the previous code snippet on how to craft claims for the GetClaims() method
string token = Encode(Encoding.UTF8.GetBytes(JObject.FromObject(header).ToString())) + "." + Encode(Encoding.UTF8.GetBytes(JObject.FromObject(GetClaims())));
string signature = Encode(rsa.SignData(Encoding.UTF8.GetBytes(token), new SHA256Cng()));
string signedClientAssertion = string.Concat(token, ".", signature);
return signedClientAssertion;
}
private static IDictionary<string, string> GetClaims()
{
//aud = https://login.microsoftonline.com/ + Tenant ID + /v2.0
string aud = $"https://login.microsoftonline.com/{tenantId}/v2.0";
string ConfidentialClientID = "00000000-0000-0000-0000-000000000000" //client id
const uint JwtToAadLifetimeInSeconds = 60 * 10; // Ten minutes
DateTime validFrom = DateTime.UtcNow;
var nbf = ConvertToTimeT(validFrom);
var exp = ConvertToTimeT(validFrom + TimeSpan.FromSeconds(JwtToAadLifetimeInSeconds));
return new Dictionary<string, string>()
{
{ "aud", aud },
{ "exp", exp.ToString() },
{ "iss", ConfidentialClientID },
{ "jti", Guid.NewGuid().ToString() },
{ "nbf", nbf.ToString() },
{ "sub", ConfidentialClientID }
};
}
Or using Powershell: https://learn.microsoft.com/en-us/azure/cosmos-db/certificate-based-authentication#create-a-self-signed-certificate
I ran into a problem with the method mentioned in the title. If I try to sign an XPS document, it runs into NullReferenceException:
at System.Windows.Xps.Packaging.XpsDocument.get_IsSignable()
at System.Windows.Xps.Packaging.XpsDocument.SignDigitally(X509Certificate certificate, Boolean embedCertificate, XpsDigSigPartAlteringRestrictions restrictions, String signatureId, Boolean testIsSignable)
at System.Windows.Xps.Packaging.XpsDocument.SignDigitally(X509Certificate certificate, Boolean embedCertificate, XpsDigSigPartAlteringRestrictions restrictions)
Any advise will appreciated.
if (sign_digitally)
{
UserCertificateSelector selector = new UserCertificateSelector();
if (selector.ShowDialog() == true)
{
var certStore = new X509Store(StoreName.My, StoreLocation.CurrentUser);
certStore.Open(OpenFlags.ReadOnly);
#if DEBUG
X509CertificateCollection collection = certStore.Certificates;
#else
X509CertificateCollection collection = certStore.Certificates.Find(X509FindType.FindByThumbprint, selector.SelectedCertificate.CertificateThumbPrint,true);
#endif
if (collection.Count > 0)
{
xpsDoc.SignDigitally(collection[0], true, XpsDigSigPartAlteringRestrictions.None);
}
}
}
...
Make sure you deal with XPS file format, not OXPS. Both can be open as XpsDocument but only XPS can be signed. You can check "XpsDocument.IsSignable" flag once you open the file - for OXPS it will be null.
I'm trying to use the c# library to download a file from an FTP. The code we are using is straight forward.
static void Main(string[] args)
{
Connect(true, true, true);
}
private static void Connect(bool keepAlive, bool useBinary, bool usePassive)
{
string RemoteFtpPath = "ftp://ftp.xxxx.ac.uk/incoming/testExtractCSVcoursesContacts.csv";
const string Username = "anonymous";
const string Password = "anonymous#xxxx.ac.uk";
var request = (FtpWebRequest)WebRequest.Create(new Uri(RemoteFtpPath));
request.Method = WebRequestMethods.Ftp.DownloadFile;
request.KeepAlive = keepAlive;
request.UsePassive = usePassive;
request.UseBinary = useBinary;
request.Credentials = new NetworkCredential(Username, Password);
request.Timeout = 30000;
try
{
var response = (FtpWebResponse)request.GetResponse();
var responseStream = response.GetResponseStream();
var reader = new StreamReader(responseStream);
var fileString = reader.ReadToEnd();
Console.WriteLine(
$"Success! keepAlive={keepAlive}, useBinary={useBinary}, usePassive={usePassive} Length={fileString.Length}");
reader.Close();
response.Close();
}
catch (Exception e)
{
Console.WriteLine(
$"Failed! keepAlive={keepAlive}, useBinary={useBinary}, usePassive={usePassive}, message={e.Message}");
}
}
`
we also tried to set passive = true with identical results.
When we run it, using wireshark we are getting : Wireshark log c#
Now we tried the same with Python and it's working just fine:
import urllib.request
data = urllib.request.urlretrieve('path')
print(data)
the wireshark log looks quite different:
So tried different things, but not able to sort this out.
Some ftp servers don't support OPTS UTF8 but still transmit file names in UTF8. (Note that 'OPTs UTF8' is NOT required by the FTP Internationalization Standard, although supporting UTF8 file names is.) The .NET Ftp classes will use the default code page if they don't get an OK response to OPTS UTF8... It's unfortunate that MS didn't provide some way to use UTF8 anyway, since this leaves you unable to transmit international file names to and from otherwise UTF8-compliant servers.
The issue is sorted after using a different library as FtpWebRequest doesn't support it
The following code works perfectly fine from my own machine (Win7 ISS7) but when I move it to a virtual server running IIS8 on a datacentre then I get the return code 150 (openingdata). I can access the ftp site via IE on this server. Is this a coding issue or configuration. Any help is greatly appreciated.
I've also tried changing UsePassive, UseBinary, no caching, to no effect and place it on an azure machine but to no avail.
private List<string> Browse()
{
// Get the object used to communicate with the server.
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(m_Url);
request.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
result.Add("Timeout = " + request.Timeout.ToString());
// This example assumes the FTP site uses anonymous logon.
request.Credentials = new NetworkCredential(m_Username, m_Password);
request.CachePolicy = new RequestCachePolicy(RequestCacheLevel.NoCacheNoStore);
if (m_Proxy != null)
{
request.Proxy = m_Proxy;
}
bool started = false;
using (FtpWebResponse response = (FtpWebResponse)request.GetResponse())
{
Stream responseStream = response.GetResponseStream();
using (StreamReader reader = new StreamReader(responseStream))
{
string line = reader.ReadLine();
while (line != null)
{
result.Add(line);
line = reader.ReadLine();
}
}
}
return result;
}
Turned out it was a program error
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(m_Url);
should have been
FtpWebRequest request = (FtpWebRequest)*Ftp*WebRequest.Create(m_Url);