• (cs)

    Ouch.  Of course the REAL wtf is this:  "Once everything went into production"

    Any ideas whose head(s) will roll?.....[6]

  • (cs) in reply to mlathe
    mlathe:

    Anonymous:
    That is nothing. I just had to write a queer piece of code myself: BOOL SomeClass::TestSomething() { if(this == NULL) return FALSE; TestSomethingAndReturnResult; } The reason was the earlier piece of code: return (pSomeObject == NULL)?FALSE:pSomeObject->TestSomething(); was crashing occasionally because some other thread would come and change pSomeObject to NULL in between the first part and second part of that line. Any kind of synchronization object was out of question because that line was being called for a few thousand objects every few milliseconds by THIS thread, not to mention the OTHER thread where pSomeObject was being modified.

    most people would just handle the null pointer exception rather then making a hack.



    Most people would know that the application talked about is a C++ application and does not have such a thing as a null pointer exception. The null pointer exception here is called SIGSEGF on Linux and some other constant in Windows' SEH mechanism, and neither is really suitable for this task.

    Yo Mama:
    You do realize, of course, that you are going to be the subject of tomorrows WTF? If a thread is getting in between

    return (pSomeObject == NULL)?FALSE:pSomeObject->TestSomething();

    and deleting the object, why is it that you believe that the exact same thing can't happen right after your check for (this == NULL)?



    It's not deleting the object, it's just setting the pointer to NULL. Setting the this pointer to NULL from a different thread is not possible anyway.

    Of course, that doesn't change the fact that the multiple threads accessing the same pointer is still a WTF.

  • rask (unregistered) in reply to anon

    Anyone above questioning the wtfness of this saying its easy to make the SOAP calls stateful using packets needs to stop programming.

     

    There are a couple fundamental problems with this encryption strategy that a simple kludge like SOAP packets isn't going to address:

    1.) Encryption over the network.  I shudder at the thought, talk about adding a massive failure point into the most necessarily secure piece of code.  100% retarded.

     

    2.) Using 3 calls when 1 would do.  Why oh why would you ever do 3 soap requests when 2 of them are essentially setting properties????  Even if they didn't run into the race condition, tripling the network latency meaningless is beyond retarded.  It reminds me of the old J2EE Entity beans where every property setter would cause a full blown transaction on the database.

  • Brian Kemp (unregistered) in reply to Yo Mama

    The C# fix to that little testing problem for this==NULL;

    lock(this){
    //statements
    }

    I'm sure there's some way to implement a critical section in your system.              

  • bigkif (unregistered) in reply to Greg

    It seems to be Java code. Nethertheless in J2EE word, EJBs can implement it very simply. So, this WTF is a small bug. But, it's a serious mistake in conception ...

  • (cs)

    Obviously, the encryption should have been performed by an outsourced service on another network:

    Function encrypt(data As String) Dim r As HttpRequest r = New HttpRequest("http://service.encryptforme.com/encrypt.asp", "post") r.Body = "data=" & UrlEncode(data) & _ "&key=" & MY_KEY & _ "&method=" & MY_ENCRYPTION_METHOD r.Execute() Return r.Response End Function

    I think this approach is bullet-proof.

  • (cs)

    You mean Oliver Klozov, the famous nude photographer, is also doing contract development in his free time? Heh.

    Way to go Alex -- this is the best anonymization I ever saw in here. Too bad the joke's totally lost on most of us devs. But then again, it's comforting to know that regulars of this site largely do not frequent adult sites.

  • BrianG (unregistered)

    Yes, I've seen this "doh" before. Because tools like WSDL2Java can so easily make web services look like classes, it is easy for an "inexperienced" programmer to think the service behaves like an object.

    BTW, me first!

  • UTU (unregistered) in reply to BrianG
    Anonymous:
    Because tools like WSDL2Java can so easily make web services look like classes, it is easy for an "inexperienced" programmer to think the service behaves like an object.


    It's not impossible (not even hard) to make a webservice behave exactly like a statefull object. However, it is another case of WTF for us for some other day I think :)
  • (cs)

    Just to cut down on peoples' cases of missing-the-WTF, Alex over-anonymized this one a bit (although I must say, he did an excellent job of keeping the original WTF intact).

    This component was actually a COM library exposing different classes, for example:

    set foo = CreateObject("Encryption.Encryption1")
    set bar = CreateObject("Encryption.Encryption2")

    Originally, these were actually separate libraries with hardcoded keys (actually, for security, the keys were split in two; half were embedded in the executable and half were supplied by external means.).  As part of our Enterprise .NET initiative, a contractor rewrote these components into a single .NET assembly exposing all of the COM objects.  The assembly merged the common parts (they all used the same set of encryption algorithms, just with different parameters); the different constructors would all construct a common Encryption object, like this:

    public Encryption1() {
        this.enc = new Encryption();
        enc.SetType("12345");
        enc.SetKey("ABCDE");
    }

    public Encryption2() {
        this.enc = new Encryption();
        enc.SetType("54321");
        enc.SetKey("FGHIJ");
    }

    Great, except for the fact that Encryption.SetType() and Encryption.SetKey() stored everything in static fields.

    So if you had to use two types of encryption...

    enc1 = new Encryption1();
    enc2 = new Encryption2();
    passenc = enc1.Encrypt("password"); // encrypts with Encryption2's settings


    crosses fingers and hopes this posts correctly  

  • Anonymaly (unregistered) in reply to Drum D.
    Drum D.:
    Alright then they fucked it up and - as any good programmer should do - tried to blame someone else.
    But WHY?
    Isn't this
    encWebSrvc = new EncryptionWebService(SERVICE_URL);

    object tied to a session or something like that? It's 11 pm now and I'm struck with hayfever so maybe someone who can still think clearly is willing to explain this to me.

    Technically, it should have only been one call to the Web service with a return value for the result.  Under the hood, each call to a Web service method makes a new HTTP request passing an XML formatted message and receiving a reply.

    There shouldn't need to be any use of a session variable at all, since there is no need for this type of service method to be a "chatty" call.  The key, type and information (or reference) to what needs to be encrypted can be passed in one fell swoop, only requiring one request instead of several requests to do one operation.

  • (cs)

    <FONT face=Garamond color=#a52a2a>IMHO, I think that consolidating the encryption tech into one "service" (substitutue "library" or any other word of your choosing) like that is possibly a small WTF .</FONT>

    <FONT face=Garamond color=#a52a2a>Going down that road, the object-oriented "yellow brick" road, could lead to even bigger headaches.  Hopefully, when something like this is implemented, you won't have to change this concentrated code that touches everything under the sun.  If you do have to change or completely revamp the "service" (like these folks), you'll end up regression testing *ALL* of those silly applications consuming that service - a testing nightmare complete with scarecrows and flying monkeys.</FONT>

    <FONT face=Garamond color=#a52a2a>Am I insane?</FONT>

    [:#]

  • Photonman (unregistered)

    [sarcasm]But I thought that web servers only handled one transaction at a time.........[/sarcasm]

    Ingenious. Since requests will never be in order, nodoby can possibly decrypt anything! Take THAT, crackers!

  • mcguire (unregistered)
    Alex Papadimoulis:

    encWebSrvc = new EncryptionWebService(SERVICE_URL);
    encWebSrvc.setEncryptionType("CFB64");
    encWebSrvc.setPrivateKeyId("42B9657F-0E9A-44EC-BCC2-F1E38770B0C2");
    return encWebSrvc.Encrypt(transactionLog);

    ... until one considers that each line requires a separate request and, as the web service is used by several applications, it takes a lot of luck that one individual thread will be lucky enough to have three consecutive requests to set the encryption type, set the key, and encrypt that data. Whoops.



    Oh. My. Lord.  Each call is an individual request.  Each request is handled from a pool of threads.  The threads are stateful.  There's nothing guaranteeing all the requests in a single "transaction" go to the same thread.

    I'm going to need a quart of tequila to rinse this one out of my brain.
  • mastmaker (unregistered) in reply to Yo Mama

    You got it wrong, Yo mama (with some ambiguous input from me)

    I should have coded (in the obscured sample) pSomeObject as m_pSomeObject.

    You see: m_pSomeObject is the member of a particular class. An instance of the class was in the process of executing the first line where m_pSomeObject got modified.

    In second case, you got INTO the m_pSomeObject and THEN check for validity of the 'this' pointer.

  • XMLord (unregistered)
    Alex Papadimoulis:

    The idea was that, because encryption is such a vital part of security, all encryption should be done in one place, with once web service, instead of within each application.



    I find it hard to follow this logic, or as I should probably say: That's the real wtf!
    Haven't they ever heard of the term "code reuse"? I really don’t get it. Why would you use a web service for this?

    <o:p> </o:p>Why not just say that since all of both Firefox and Photoshop need to calculate the positioning of different pixels, it will all be done using a web service?

  • mastmaker (unregistered) in reply to CornedBee
    CornedBee:
    mlathe:

    Anonymous:
    That is nothing. I just had to write a queer piece of code myself: BOOL SomeClass::TestSomething() { if(this == NULL) return FALSE; TestSomethingAndReturnResult; } The reason was the earlier piece of code: return (pSomeObject == NULL)?FALSE:pSomeObject->TestSomething(); was crashing occasionally because some other thread would come and change pSomeObject to NULL in between the first part and second part of that line. Any kind of synchronization object was out of question because that line was being called for a few thousand objects every few milliseconds by THIS thread, not to mention the OTHER thread where pSomeObject was being modified.

    most people would just handle the null pointer exception rather then making a hack.



    Most people would know that the application talked about is a C++ application and does not have such a thing as a null pointer exception. The null pointer exception here is called SIGSEGF on Linux and some other constant in Windows' SEH mechanism, and neither is really suitable for this task.

    Yo Mama:
    You do realize, of course, that you are going to be the subject of tomorrows WTF? If a thread is getting in between

    return (pSomeObject == NULL)?FALSE:pSomeObject->TestSomething();

    and deleting the object, why is it that you believe that the exact same thing can't happen right after your check for (this == NULL)?



    It's not deleting the object, it's just setting the pointer to NULL. Setting the this pointer to NULL from a different thread is not possible anyway.

    Of course, that doesn't change the fact that the multiple threads accessing the same pointer is still a WTF.

    I don't see a WTF in allowing the multiple threads to access the same pointer.

    I routinely create thousands of fixed objects where one thread responds to events occurring in any of these objects while another thread comes around checking for any timer-related events that need to be GENERATED. (Guess I should be more specific in defining the events to make myself clear and justified, but I cannot do that without risking my anonymity)

  • Michael K. Campbell (unregistered)

    Man. The WTF here isn't JUST that this crack dev team was clue-less on the nature of web services, but on the nature of services, or even oop, in general.

    WHAT THE HELL is the point of making all of your clients
    1) know their encryption keys
    2) send them up in plain text to a WS?

    The point of a web service would be to:
    1) ENCAPSULATE encryption
    2) protect the keys.

    Meaning that consumers might pass in some identifier which would be used to determine what KIND of encryption/decryption (including the keys) was desired.


  • Willam D. Paulaphile (unregistered)

    CORBA sucks because you end up making lots of network calls to manipulate an object. We switched to Web Services because now we only make ... umm... wait...

  • (cs) in reply to fmobus
    fmobus:
    (it chewed my post. let's try again)
    There are some WTFs in the OP:
    1. Encryption as webservice is a WTF in itself, even if done "correctly": in order to encrypt your transaction, you need to send it plain-text; in order to decrypt, you need to send your PRIVATE KEY in plain text and receive your transaction in plain-text again. This begs for interception. Encryption should ALWAYS be done locally.

    I'd really get a laugh out of this if they decide to use SSL to send the plaintext keys. Encrypting to encrypt.

  • Anonymous Coward (unregistered)

    I don't understand . . . someone care to explain?

  • John Melville (unregistered)

    Uh.. Am I the only one who finds it wierd to send (presumably plaintext) messages to a webservice so that they can be "securely encrypted."

    WTF

  • kbiel (unregistered) in reply to Greg
    Anonymous:
    .net webservices allow for sessions. Not terribly hard to implement it; it's just missing from the code.


    OK, ignoring the fact that the requirement for encryption via a web service is WTF all in itself, what the hell are sesssions going to do for it?  What's wrong with:

    encWebSrvc = new EncryptionWebService(SERVICE_URL);
    return encWebSrvc.Encrypt("CFB64", "42B9657F-0E9A-44EC-BCC2-F1E38770B0C2", transactionLog);

    I guess encryption isn't slow enough by itself, so they had to make not 1, not 2, but 3 latency filled HTTP calls.  That's just brillant.
  • (cs) in reply to Anonymous Coward
    Anonymous:
    I don't understand . . . someone care to explain?


    Here's a thought - try reading all the preceeding posts before you yourself post.
  • (cs)


    perl -e "print map chr,112,101,114,108,32,45,101,32,34,112,114,105,110,116,32,109,97,112,32,99,104,114,44,51,57,44,56,54,44,55,57,44,56,52,44,54,57,44,51,50,44,55,48,44,55,57,44,56,50,44,51,50,44,52,57,44,52,56,44,52,56,44,51,55,44,51,50,44,56,55,44,54,57,44,54,54,44,51,50,44,56,51,44,54,57,44,56,50,44,56,54,44,55,51,44,54,55,44,54,57,44,56,51,44,52,52,44,51,50,44,55,56,44,55,57,44,56,55,44,51,51,44,51,51,44,51,51,44,51,57,59,34;"

    [<:o)]
  • (cs)

    The real WTF is that they're using method "setPrivateKeyId" when requesting encryption. The method is obviously misnamed, they meant to call it "setKeyPairId".

    Anyway, nice. They're sending key IDs, but the content goes over the network in plaintext in both directions.

    Hey I know, let's take care of the transmitted-in-plaintext problem by using a HTTPS transport. With that, the connection to... the encryption... server... is... encrypted...

    There's still something wrong with this. Ummm...

    I know! Let's not only send key IDs, but also plaintext IDs and encryption IDs. This way, the ciphertext is never transmitted over the network.

    Client: "Hey, server, I need to encrypt transaction log with id 4CCA08D2-DAF7-11DA-9061-F1E38770B0C2 using key pair id 42B9657F-0E9A-44EC-BCC2-F1E38770B0C2 and algorithm CFB64."

    Server: "Sure thing! Use ciphertext id 42A81B0A-DAF7-11DA-A9E4-F1E38770B0C!"

    Client: "Nice! What's a ciphertext id, anyway?"

    Server: "Beats me. What's a transaction log id, anyway?"

  • rask (unregistered) in reply to TomCo
    TomCo:

    <FONT face=Garamond color=#a52a2a>IMHO, I think that consolidating the encryption tech into one "service" (substitutue "library" or any other word of your choosing) like that is possibly a small WTF .</FONT>

    <FONT face=Garamond color=#a52a2a>Going down that road, the object-oriented "yellow brick" road, could lead to even bigger headaches.  Hopefully, when something like this is implemented, you won't have to change this concentrated code that touches everything under the sun.  If you do have to change or completely revamp the "service" (like these folks), you'll end up regression testing *ALL* of those silly applications consuming that service - a testing nightmare complete with scarecrows and flying monkeys.</FONT>

    <FONT face=Garamond color=#a52a2a>Am I insane?</FONT>

    [:#]

     

    I don't think advocating a method like:

    return EncryptionWebService.Encrypt(SERVICE_URL, "CFB64", "42B9657F-0E9A-44EC-BCC2-F1E38770B0C2", transactionLog);
    

    but rather instead:

    >
    encWebSrvc = new EncryptionWebService(SERVICE_URL);  //Construct an object
    encWebSrvc.setEncryptionType("CFB64"); //set a property
    encWebSrvc.setPrivateKeyId("42B9657F-0E9A-44EC-BCC2-F1E38770B0C2"); //set a property
    return encWebSrvc.Encrypt(transactionLog); //Send built up object above via XML to server defined by WSDL schema
    I really don't see how this way conctrates the code anymore, but still concentrating network traffic. Not to mentioning completely removing need for a stateful webservice.
  • Frank (unregistered)

    First???

    I love the idea of clear-text data floating over the network to be encrypted being regarded as inherently more secure than encrypting it before sending...

  • (cs) in reply to Drum D.

    By the "three consecutive requests" explanation, it seems to be a problem with synchronization in a multi-threaded environment. I guess the encryption settings were stored statically, or in some kind of global object, and kept overwriting each other. But what do I know...

  • quirk (unregistered) in reply to mastmaker

        That is nothing. I just had to write a queer piece of code myself:

        BOOL SomeClass::TestSomething()
        {
        if(this == NULL)
        return FALSE;
        TestSomethingAndReturnResult;
        }

        The reason was the earlier piece of code:

        return (pSomeObject == NULL)?FALSE:pSomeObject->TestSomething();

        was crashing occasionally because some other thread would come and change pSomeObject to NULL in between the
        first  part and second part of that line.


        Any kind of synchronization object was out of question because that line was being called for a few thousand objects
        every few milliseconds by THIS thread, not to mention the OTHER thread where pSomeObject was being modified.  


    Erm, that doesn't fix the problem.  Couldn't the other thread still change pSomeObject to NULL during TestSomethingAndReturnResult()?

  • tdog (unregistered) in reply to ogilmor
    ogilmor:

    Ouch.  Of course the REAL wtf is this:  "Once everything went into production"

    Any ideas whose head(s) will roll?.....[6]

    QA of course.  They are paid to be the fall guys. 

  • Daniel (unregistered)

    Not too bright, but hardly worthy of a WTF.  It's not like he's the first programmer to introduce a race conditioning or forget to enable session keys. I can easily envision a perfectly talented programmer screwing this up on a bad day.

  • (cs) in reply to quirk
     return (pSomeObject == NULL)?FALSE:pSomeObject->TestSomething();
    
    Erm,
    that doesn't fix the problem.  Couldn't the other thread still change
    pSomeObject to NULL during TestSomethingAndReturnResult()?

    Change the member to

    volatile SomeObject* pSomeObject;

    add a check for FileNotFound and take an early lunch. (Though make sure you spawn a new thread to do a separate check, to help preempt any unexpected thread scheduling.)

  • (cs) in reply to anon

    As the crack team built SOA with with crumple zones and loose coupling, the application surely gracefully degrades and operates without the encryption service, using a no-op local cypher.

    With plaintext keys no longer being sent, there is less chance of keys being obtained by an intermediary. So, the graceful degredation gives the application even greater protection when it needs it most during external service instability. Brilliant!

  • (cs) in reply to razz

    BAD COMBOS:

    mod_php + Apache + gettext + nowdays OS libs where not thread safe.
    AND gettext required changes on enviroment keys, that are global on threads.

    result: multilugual chaos
    (fortunally enough, easy to solve)

    Apache2 (a thread based application) + poorly written regular expresions + windows

    result: 100% cpu, Apache2 freezze, no network IO.
    --Tei

  • (cs) in reply to CornedBee

    My heartfelt thank you to CornedBee for demonstrating that there is somebody else on this board with a grasp of how a computer actually works.

    IMO everybody else posting about threads has a lot to learn (and thus realise the total paradign shift in app design of single vs multi-threading).

  • (cs) in reply to ishmaeel
    ishmaeel:

    You mean Oliver Klozov, the famous nude photographer, is also doing contract development in his free time? Heh.

    Way to go Alex -- this is the best anonymization I ever saw in here. Too bad the joke's totally lost on most of us devs. But then again, it's comforting to know that regulars of this site largely do not frequent adult sites.

    Doh! I totally missed that completely obvious pseudonym. Am I the only one who missed All Of Her Clothes Off?

  • (cs) in reply to Alex Papadimoulis
    Alex Papadimoulis:
    ishmaeel:

    You mean Oliver Klozov, the famous nude photographer, is also doing contract development in his free time? Heh.

    Way to go Alex -- this is the best anonymization I ever saw in here. Too bad the joke's totally lost on most of us devs. But then again, it's comforting to know that regulars of this site largely do not frequent adult sites.

    Doh! I totally missed that completely obvious pseudonym. Am I the only one who missed All Of Her Clothes Off?



    you mean you did that on accident?  amazing.
  • (cs)
    Encryption Initiative Team:
    Our code is elegant and simple, and can't possibly fail.


    *Sigh* Do people ever learn? Maybe this is a place for a new rule of thumb in sw project management: "Whenever things go wrong, start investigating where the most confident and arrogant developers have been playing."
  • ihavenoname (unregistered) in reply to mastmaker

    <font size="2">I belive that C++ has an incredible feature known as...local variables. In other words, instead of adding a dreadful NULL check in the method itself, you could have simply changed the call sites to:

    ptmp = pSomeObject;
    return (ptmp ==  NULL) ? FALSE : ptmp->TestSomething();

    Of course, you'd better be sure that pSomeObject was declared as a volatile pointer...
    </font>

  • nlight (unregistered)

    first:p

  • pirri (unregistered)

    Don't they know what "stateless" mean?

  • Chris vanderheyden (unregistered) in reply to Greg

    Apparently there is a lot of confusion on how to use these these WS service thingies on the Daily
    It should have been implemented.

    encWebSrvc = new EncryptionWebService(SERVICE_URL);
    return encWebSrvc.Encrypt("CFB64","42B9657F-0E9A-44EC-BCC2-F1E38770B0C2", transactionLog);

  • (cs) in reply to lrb

    lrb:
    BTW where the hell was the testing?



    <font size="2">To : Development team head
    From : Testing team head

    Bill,
    We've run into a few critical problems with your app, and have had to stop testing, viz.

    "private key" textbox:
    </font>
    • <font size="2">I enter "aaa" in the box, and I get the message back "incorrectly formatted private key, key should be of the form 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'".  Frankly, if the  program knows my private key, why bother having a textbox at all?  Still, carrying on...</font>
    • <font size="2">I enter "</font><font size="2">XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX</font><font size="2">" in the box, as requested.  I get jibberish back, which is hardly surprising as, on checking, I find that my private key is actually  "9793D48B-B64A-4D09-9650-EAC101D7EE53".  I get no error message in this case, despite the fact that this is not my private key.</font>
    <font size="2">
    It is my opinion that, as it stands, your app is unusable - it patently knows that 'aaa' is not my private key (and, by logic, what my private key actually is), but then gives me back an incorrect private key.  When I try to use that key, and despite the app knowing it's not mine, it blithely carries on as though nothing was wrong.

    This is without mentioning the issues with the "Name" and "Address" boxes...

    Yours,

    </font><font size="2">Jeff</font>


    Simon

  • (cs) in reply to Me
    Anonymous:
    I don't get it.


    Each app is generating a separate request to specify their key to the web service and to then encrypt using that private key.  But in-between specifying the key and encrypting, another application would make their request to specify THEIR key, so when the first app asked for their data to be encrypted, it would be done using the second app's key.  Hence the reference to "race condition".

    Simon

  • Martin (unregistered)

    I am not into web services, but couldn't this easily be solved using some sort of sessions ...

    Btw: first!

    Marty

  • ToshiroDK (unregistered)

    It's a sort of Transaction-based Timecapsule

  • (cs) in reply to fmobus
    fmobus:
    1. Encrypting with the PRIVATE KEY? Is that anonymization problem? You should never send you private key thru plain text... Alex, is this an anonymization (sp?) typo?


    Maybe the example given was not a call for encryption, but for signing...
  • (cs) in reply to Yo Mama
    Anonymous:

    Anonymous:
    That is nothing. I just had to write a queer piece of code myself: BOOL SomeClass::TestSomething() { if(this == NULL) return FALSE; TestSomethingAndReturnResult; } The reason was the earlier piece of code: return (pSomeObject == NULL)?FALSE:pSomeObject->TestSomething(); was crashing occasionally because some other thread would come and change pSomeObject to NULL in between the first part and second part of that line. Any kind of synchronization object was out of question because that line was being called for a few thousand objects every few milliseconds by THIS thread, not to mention the OTHER thread where pSomeObject was being modified.

    You do realize, of course, that you are going to be the subject of tomorrows WTF?  If a thread is getting in between

    return (pSomeObject == NULL)?FALSE:pSomeObject->TestSomething();

    and deleting the object, why is it that you believe that the exact same thing can't happen right after your check for (this == NULL)?

     


    ... or between the (pSomeObject == NULL) test and the dereferencing of TestSomething(), or at anytime during TestSomethingAndReturnResult?

    Seriously, WTF?

    Today's proper WTF isn't that WTF to me; OK so they forgot about race conditions or atomicity of transactions. Not a major problem to fix.

  • Somebody (unregistered)

    There are several problems with the above:

    1. Encryption should be done on the same computer, otherwise unencrypted data can be sniffed.

    2. The encryption should be on one call ie. Encrypt(string type, string key, byte[] data).
    This avoid 2 calls and allows the server to do proper locking (if the encryption is not thread-safe).

    3. If you want to avoid code duplication use a library not a web service.

    4. The web service introduces a single point of failure (encryption server goes down) for several applications.

    This is not security. It's stupidity!

Leave a comment on “The Encryption Initiative”

Log In or post as a guest

Replying to comment #:

« Return to Article