WSS4J SHA1 value different when using IBM JDK 7 versus Oracle JDK 7 - wss4j

I need help understanding why I am getting a different SHA1 digest value when using IBM JDK 7 versus Oracle JDK 7 along with the WSS4J library.
What I am trying to do now is force the use of Sun JCE, having moved Sun JARs to my IBM JDK. The reason is because my digest values are coming out right using Oracle JDK 7 and the digest values match the IRS's web service's calculation of them.
I am using canonicalization (C14N_EXCL_WITH_COMMENTS) in my code. But I am getting a different SHA1 hash for a an XML element when using IBM JDK 7 versus Oracle JDK 7. The XML that I am calculating a hash value for only has constants in it. Nothing changes in the below XML but I get different hash values:
<urn:ACATransmitterManifestReqDtl
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
wsu:Id="aCATransmitterManifestReqDtl">
<urn:PaymentYr>2015</urn:PaymentYr>
<urn:PriorYearDataInd>0</urn:PriorYearDataInd>
<urn:TransmissionTypeCd>O</urn:TransmissionTypeCd>
<urn:TestFileCd>T</urn:TestFileCd>
</urn:ACATransmitterManifestReqDtl>
I am getting a different SHA1 value with the following code:
WSSecSignature wsSecSignature = new WSSecSignature(config);
wsSecSignature.setX509Certificate(signingCert);
wsSecSignature.setUserInfo(alias, new String(keystorePassword.toCharArray()));
wsSecSignature.setUseSingleCertificate(true);
wsSecSignature.setKeyIdentifierType(WSConstants.X509_KEY_IDENTIFIER);
wsSecSignature.setDigestAlgo(WSConstants.SHA1);
wsSecSignature.setSignatureAlgorithm(WSConstants.RSA_SHA1);
wsSecSignature.setSigCanonicalization(WSConstants.C14N_EXCL_WITH_COMMENTS);
try {
Document document = toDocument(message);
WSSecHeader secHeader = new WSSecHeader();
//secHeader.setMustUnderstand(true);
secHeader.insertSecurityHeader(document);
WSSecTimestamp timestamp = new WSSecTimestamp();
timestamp.setTimeToLive(signatureValidityTime);
document = timestamp.build(document, secHeader);
List<WSEncryptionPart> wsEncryptionParts = new ArrayList<WSEncryptionPart>();
WSEncryptionPart timestampPart = new WSEncryptionPart("Timestamp",
WSConstants.WSU_NS, "");
WSEncryptionPart aCATransmitterManifestReqDtlPart = new WSEncryptionPart(
"ACATransmitterManifestReqDtl",
"urn:us:gov:treasury:irs:ext:aca:air:7.0", "");
WSEncryptionPart aCABusinessHeaderPart = new WSEncryptionPart(
"ACABusinessHeader",
"urn:us:gov:treasury:irs:msg:acabusinessheader", "");
wsEncryptionParts.add(timestampPart);
wsEncryptionParts.add(aCATransmitterManifestReqDtlPart);
wsEncryptionParts.add(aCABusinessHeaderPart);
wsSecSignature.setParts(wsEncryptionParts);
Properties properties = new Properties();
properties.setProperty("org.apache.ws.security.crypto.provider",
"org.apache.ws.security.components.crypto.Merlin");
Crypto crypto = CryptoFactory.getInstance(properties);
KeyStore keystore = KeyStore.getInstance("JKS");
EDIT WHAT I'VE TRIED, LOOKING FOR HELP FORCING PROVIDER TO BE SUN JCE
I was hoping to enter the following code Provider sunJCE = Security.getProvider("SunJCE") but it is coming back null
I edit my java.security file to include the sun.security.provider.SunJCE:
security.provider.1=com.ibm.jsse2.IBMJSSEProvider2
security.provider.2=com.ibm.crypto.provider.IBMJCE
security.provider.3=com.ibm.security.jgss.IBMJGSSProvider
security.provider.4=com.ibm.security.cert.IBMCertPath
security.provider.5=com.ibm.security.sasl.IBMSASL
security.provider.6=com.ibm.xml.crypto.IBMXMLCryptoProvider
security.provider.7=com.ibm.xml.enc.IBMXMLEncProvider
security.provider.8=com.ibm.security.jgss.mech.spnego.IBMSPNEGO
security.provider.9=sun.security.provider.Sun
security.provider.10=com.sun.crypto.provider.SunJCE
security.provider.11=sun.security.provider.Sun
security.provider.12=sun.security.rsa.SunRsaSign
security.provider.13=sun.security.jgss.SunProvider
And I am programmatically trying to use the SunJCE as follows:
Provider sunJCE = Security.getProvider("SunJCE");
if (sunJCE != null) {
logger.info("SunJCE Java Cryptography Extension (JCE) to provide cryptographic, key and hash algorithms : IBMJCE will be removed");
try {
Security.removeProvider("IBMJCE");
Security.insertProviderAt(sunJCE, 1);
} catch (SecurityException se) {
logger.info("Cannot move SunJCE to top priority", se);
}
}
I also moved these JARs from Oracle JDK 7 to IBM JDK 7: (1) copied the sunjce_provider.jar jar file in to WAS_HOME/java/jre/lib/ext
folder and (2) copied the jce.jar file in to was_home/java/jre/lib

Related

Elastic-Cloud Not Receiving Data from Serilog Sink

I set up an Elastic Cloud to offload my local elasticsearch config (as one does), but for reasons unknown to me, I can't get it to show any logs in Elastic Cloud, despite it working fine locally.
The code I got: (modified for privacy reasons)
//var uri = new Uri("http://localhost:9200"); // old one
var uri = new Uri("https://my-server.kb.eastus2.azure.elastic-cloud.com:9243");
var sinkOptions = new ElasticsearchSinkOptions(uri)
{
AutoRegisterTemplate = true,
ModifyConnectionSettings = x => x.BasicAuthentication("elastic", "the password I was given"),
IndexFormat = $"test-logs-{env.EnvironmentName?.ToLower().Replace('.', '-')}-{DateTime.Now:yyyy-MM}",
};
Log.Logger = new LoggerConfiguration()
.ReadFrom.Configuration(config)
.Enrich.FromLogContext()
.Enrich.WithMachineName()
.WriteTo.Console()
.WriteTo.Elasticsearch(sinkOptions)
.Enrich.WithProperty("Environment", env.EnvironmentName)
.CreateLogger();
There are two possible reasons I can think of that might be the cause of this not working:
The credentials are wrong
The Uri is wrong
Every solution I've been given so far has provided the data in this fashion, and nowhere does it say what the URI I'm supposed to use looks like.
I get no errors.
I get no warnings.
I get no logs.
What am I doing wrong here?
The issue was using the incorrect uri. I wrote
my-server.kb.eastus2.azure.elastic-cloud.com:9243 rather than
my-server.es.eastus2.azure.elastic-cloud.com:9243.
Note the very tiny difference that is kb vs es in the url

Java 8 kerberos constrained delegation

Is there any example on how to do constrained delegation with Java 8/7. I tried searching around with no luck
Best Regards
Here is the Java 8 code snippet that allows to generate a SPNEGO token with TGS ticket for an impersonated user:
GSSManager manager = GSSManager.getInstance();
GSSName userName = manager.createName("targetUser", GSSName.NT_USER_NAME);
GSSCredential impersonatedUserCreds =
((ExtendedGSSCredential)serviceCredentials).impersonate(userName);
final Oid KRB5_PRINCIPAL_OID = new Oid("1.2.840.113554.1.2.2.1");
GSSName servicePrincipal =
manager.createName("HTTP/webservice-host.domain.ltd", KRB5_PRINCIPAL_OID);
ExtendedGSSContext extendedContext =
(ExtendedGSSContext) manager.createContext(servicePrincipal,
new Oid("1.3.6.1.5.5.2"),
impersonatedUserCreds,
GSSContext.DEFAULT_LIFETIME);
final byte[] token = extendedContext.initSecContext(new byte[0], 0, 0);
Beware extendedContext is not established yet. Multiple rounds with server may be required.
A simple demonstration code is available at https://github.com/ymartin59/java-kerberos-sfudemo
You may also refer to the follow project code: https://github.com/tellisnz/collared-kerberos

Transition from cipher 2.0 to 3.0 fails. Error 26 on attempt to read

I've used sqlcipher for 2 years. Yesterday I've upgraded to version 3.0.1 and tried to compile sqlcipher including arm64.
If I install new version of my app I can use new cipher lib without any problems.
But when I try to upgrade my previous version with DB made with sqlcipher 2.0 I get error 26.
It seems that new cipher can't decrypt my DB.
Also I tried to compile without arm64 support. The same problem.
I've solved my problem by using
PRAGMA cipher_migrate
which help to migrate from older DB structures to sqlcipher 3.0 (Details).
It must be executed right after setting the key.
If you want to read old DB (1.X/2.X) with new sqlcipher 3.0 use
PRAGMA kdf_iter = 4000
to set old value for kdf_iter. Now it equals 64,000 (Details)
In terms of lib sqlite db connection looks as follows:
int errorCode = SQLITE_ERROR;
sqlite3 *database = NULL;
errorCode = sqlite3_open_v2(path, &database, SQLITE_OPEN_READWRITE, NULL);
if (errorCode == SQLITE_OK) {
errorCode = sqlite3_key(database, key, (int)strlen(key));
}
if (errorCode == SQLITE_OK) {
errorCode = sqlite3_exec(database, "PRAGMA kdf_iter = 4000", NULL, NULL, NULL);
}

Firebird connection to remote server using FbConnectionStringBuilder

We're having trouble connecting to a remote Firebird server using the .NET provider FbConnectionStringBuilder class. We can connect to a local database file in either embedded or server mode however when it comes to establishing a connection to a remote server we can't establish the connection.
We assign properties of the FbConnectionStringBuilder class with the following code (server mode). I have omitted the code which assigns properties for embedded mode.
var cs = new FbConnectionStringBuilder
{
Database = databaseSessionInfo.PathAbsoluteToDatabase,
Charset = "UTF8",
Dialect = 3,
};
cs.DataSource = databaseSessionInfo.Hostname;
cs.Port = databaseSessionInfo.Port;
cs.ServerType = (FbServerType)databaseSessionInfo.Mode;
cs.Pooling = true;
cs.ConnectionLifeTime = 30;
if (databaseSessionInfo.UseCustomUserAccount)
{
cs.UserID = databaseSessionInfo.Username;
cs.Password = databaseSessionInfo.Password;
}
else
{
cs.UserID = Constants.DB_DefaultUsername;
cs.Password = Constants.DB_DefaultPassword;
}
Pretty straightforward. Our software contains a connection configuration screen whereby a user can supply different connection properties. These properties get assigned to the FbConnectionStringBuilder class using the code above.
The connection builder class outputs a connection string in the following format:
initial catalog="P:\Source\database.fdb";character set=UTF8;dialect=3;data source=localhost;port number=3050;server type=Default;pooling=True;connection lifetime=30;user id=USER;password=example
However literature on Firebird connection strings as indicated on this page (Firebird Connection Strings) talk of a different structure. I can only assume the FbConnectionStringBuilder class builds a Firebird connection string satisfying the requirements of Firebird.
Does the FbConnectionStringBuilder class append the hostname to the connection string correctly?
The Firebird server is running on the server. I assume there is no need to install it on the client?
What libraries need to be installed with the client to support a remote server connection?
Are we doing this right?
Any advice is appreciated.
Answering your questions:
1) Yes it will.
2) Correct, the client library will connect over the network.
3) If you use the ADO library, just FirebirdSql.Data.FirebirdClient.dll
4) Maybe, I dont know if this will help but this is how I connect.
FbConnectionStringBuilder ret = new FbConnectionStringBuilder();
ret.DataSource = Host;
ret.Port = Port;
ret.Database = Database;
ret.UserID = User;
ret.Password = Password;
ret.Charset = CharacterSet;
FbConnection ret = new FbConnection(connectionString);
Interestingly, what is the absolute path you are providing to the StringBuilder ? Is it the server absolute path, or some kind of network mapped drive?
Also, I assume you've reviewed firewall settings and allowing port 3050 inbound.

EWS. How to change DateTimeCreate property via EWS Proxy Classes

I write client application that uses Exchange Web Services Proxy Classes in order to connect to Exchange Web Services. Sometimes, I need create ItemType object and make it looks like as received letter. Therefore I need set up such properties of ItemType as DateTimeSent, DateTimeCreate, DateTimeReceived, but they haven’t public set assessTherefore I need set up such properties of ItemType as DateTimeSent, DateTimeCreate, DateTimeReceived, but they haven’t public set assessor.
I found resolve for some of them via MAPI properties:
ItemType newItem = xmlParser.LoadItem(); //info for newItem takes from xml
newItem.ExtendedProperty = new ExtendedPropertyType[1];
PathToExtendedFieldType q = new PathToExtendedFieldType();
q.PropertyTag = "3590"; //DeliveryTime
q.PropertyType = MapiPropertyTypeType.SystemTime;
newItem.ExtendedProperty[0] = new ExtendedPropertyType();
newItem.ExtendedProperty[0].ExtendedFieldURI = q;
newItem.ExtendedProperty[0].Item = new System.DateTime(2014, 5, 5, 5, 5, 5).ToString("yyyy-MM-ddTHH:mm:ssZ");
Well, it works for DateTimeSent and DateTimeReceived, but not for DateTimeCreate. ES dont give any errors, but DateTimeCreate doesnt change. I tried to UpdateItem with DateTimeCreate propery, but there was no result (update another properties runs fine).
P.S. MAPI ID for CreationTime: 0x3007.
Can someone help me with this problem?
I finally found a solution for this.
Source: https://social.msdn.microsoft.com/Forums/en-US/40a29c69-96d3-488b-8f0e-911dd5f04086/setting-a-emailmessage-datetimesent-and-isdraft?forum=exchangesvrdevelopment
You have to set 3 Extended MAPI properties PR_MESSAGE_FLAGS, PR_MESSAGE_DELIVERY_TIME, and PR_CLIENT_SUBMIT_TIME. Make sure when setting the Time you use UTC time.
For example:
EmailMessage emUploadEmail = new EmailMessage(service);
emUploadEmail.MimeContent = new MimeContent("us-ascii", bdBinaryData1);
// PR_CLIENT_SUBMIT_TIME
emUploadEmail.SetExtendedProperty(new ExtendedPropertyDefinition(57,MapiPropertyType.SystemTime), DateTime.Now.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ"));
// PR_MESSAGE_DELIVERY_TIME
emUploadEmail.SetExtendedProperty(new ExtendedPropertyDefinition(3590, MapiPropertyType.SystemTime), DateTime.Now.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ"));
// PR_MESSAGE_FLAGS
emUploadEmail.SetExtendedProperty(new ExtendedPropertyDefinition(3591,MapiPropertyType.Integer),"1");
emUploadEmail.Save(WellKnownFolderName.Inbox);
Create and last modified dates are read-only and cannot be set. The store provider updates these properties internally.

Resources